summaryrefslogtreecommitdiff
path: root/TAO/examples/POA/Forwarding/MyFooServant.cpp
blob: 2a64431cba6428416d62b761f2b9eb9e340e7bfd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
// $Id$

//==========================================================================
//
//
// = FILENAME
//     MyFooServant.cpp
//
// = DESCRIPTION
//     This is a simple foo servant implementation
//
// = AUTHOR
//     Irfan Pyarali
//
//==========================================================================

#include "tao/corba.h"
#include "MyFooServant.h"

ACE_RCSID(Forwarding, MyFooServant, "$Id$")

// Constructor
MyFirstFooServant::MyFirstFooServant (CORBA::ORB_ptr orb_ptr,
                                      PortableServer::POA_ptr poa_ptr,
                                      CORBA::Long value,
                                      CORBA::Object_ptr forward_to_ptr)
  : orb_ (CORBA::ORB::_duplicate (orb_ptr)),
    poa_ (PortableServer::POA::_duplicate (poa_ptr)),
    value_ (value),
    forward_to_var_ (CORBA::Object::_duplicate (forward_to_ptr))
{
  if (CORBA::is_nil (this->forward_to_var_.in ()))
    ACE_DEBUG ((LM_DEBUG,
                "POA approach: Forward_to is nil!\n"));

  // Assign this object a dummy I/O descriptor.  Note that even though
  // we open this file "Write Only" we still need to use the
  // ACE_Event_Handler::NULL_MASK when registering this with the
  // ACE_Reactor (see below).
  this->handle_ = ACE_OS::open (ACE_DEV_NULL, O_WRONLY);
  ACE_ASSERT (this->handle_ != ACE_INVALID_HANDLE);

  // Register handle.  Note that NULL_MASK is used to keep the
  // ACE_Reactor from calling us back on the ACE_DEV_NULL descriptor.
  ACE_Reactor_Mask mask = ACE_Event_Handler::NULL_MASK;
  int result = this->orb_->orb_core ()->reactor ()->
    register_handler (this->handle_, this, mask);
  ACE_ASSERT (result == 0);
  ACE_UNUSED_ARG (result);
}

// Destructor
MyFirstFooServant::~MyFirstFooServant (void)
{
  ACE_Reactor_Mask mask = ACE_Event_Handler::NULL_MASK;
  int result = this->orb_->orb_core ()->reactor ()->
    remove_handler (this->handle_, mask);
  ACE_ASSERT (result == 0);
  ACE_UNUSED_ARG (result);
}

// Return the Default POA of this Servant
PortableServer::POA_ptr
MyFirstFooServant::_default_POA (CORBA::Environment &/*env*/)
{
  return PortableServer::POA::_duplicate (this->poa_.in ());
}

// Return this->value
CORBA::Long
MyFirstFooServant::doit (CORBA::Environment &/*env*/)
  ACE_THROW_SPEC ((CORBA::SystemException))
{
  return this->value_++;
}

void
MyFirstFooServant::shutdown (CORBA::Environment &/*env*/)
  ACE_THROW_SPEC ((CORBA::SystemException))
{
  this->orb_->shutdown();
}


void
MyFirstFooServant::forward (CORBA::Environment &ACE_TRY_ENV)
  ACE_THROW_SPEC ((CORBA::SystemException,
                   Foo::Cannot_Forward))
{
  ACE_DEBUG ((LM_DEBUG,
              "MyFirstFooServant::forward: being called\n"));
  if (!CORBA::is_nil (this->forward_to_var_.in ()))
    {
      //
      // This is a *hack*!  We cannot ask the POA to replace us while
      // the upcall is still in progress.  So we ask the Reactor to
      // wake us up as soon as this upcall completes.  At that time
      // (in handle_input), we ask the POA to replace us.
      //

      int result = this->orb_->orb_core ()->reactor ()->ready_ops
        (this->handle_,
         ACE_Event_Handler::READ_MASK,
         ACE_Reactor::ADD_MASK);
      ACE_ASSERT (result != -1);
      ACE_UNUSED_ARG (result);
    }
  else
    {
      ACE_DEBUG ((LM_DEBUG,
                  "POA approach: Forward_to refenence is nil.\n"));
      ACE_THROW (Foo::Cannot_Forward ());
    }
}

int
MyFirstFooServant::handle_input (ACE_HANDLE)
{
  ACE_DECLARE_NEW_CORBA_ENV;

  ACE_TRY
    {
      PortableServer::ObjectId_var oid =
        this->poa_->servant_to_id (this, ACE_TRY_ENV);
      ACE_TRY_CHECK;

      PortableServer::Servant servant = this->poa_->_servant ();
      ACE_ASSERT (servant != 0);

      void *ptr = servant->_downcast ("IDL:omg.org/PortableServer/POA:1.0");
      POA_PortableServer::POA *poa = (POA_PortableServer::POA *) ptr;
      TAO_POA *tao_poa = ACE_dynamic_cast (TAO_POA *, poa);

      tao_poa->forward_object (oid.in (),
                               this->forward_to_var_.in (),
                               ACE_TRY_ENV);
      ACE_TRY_CHECK;
    }
  ACE_CATCHANY
    {
      ACE_ASSERT (1 == 0);
    }
  ACE_ENDTRY;

  return 0;
}

// Second Foo

// Constructor
MySecondFooServant::MySecondFooServant (CORBA::ORB_ptr orb_ptr,
                                        MyFooServantLocator *locator_ptr,
                                        CORBA::Long value)
  : orb_ (CORBA::ORB::_duplicate (orb_ptr)),
    locator_ptr_ (locator_ptr),
    value_ (value)
{
}

// Destructor
MySecondFooServant::~MySecondFooServant (void)
{
}


// Return this->value
CORBA::Long
MySecondFooServant::doit (CORBA::Environment &/*env*/)
  ACE_THROW_SPEC ((CORBA::SystemException))
{
  return this->value_++;
}

void
MySecondFooServant::forward (CORBA::Environment &ACE_TRY_ENV)
  ACE_THROW_SPEC ((CORBA::SystemException,
                   Foo::Cannot_Forward))
{
  // forward the forwarding request to the Servant Locator :-) This is
  // kind of a loop back, but it is correct only the IDL interface can
  // be assumed !!
  this->locator_ptr_->forward (ACE_TRY_ENV);
  ACE_CHECK;
}


void
MySecondFooServant::shutdown (CORBA::Environment &/*env*/)
  ACE_THROW_SPEC ((CORBA::SystemException))
{
  this->orb_->shutdown();
}