summaryrefslogtreecommitdiff
path: root/TAO/examples/POA/On_Demand_Loading/Servant_Activator.cpp
blob: b370c95ac30cb4fdbc0b7925b3b0262d76593ee5 (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
// $Id$

// ============================================================================
//
// = LIBRARY
//     TAO/tests/POA/On_Demand_Loading
//
// = FILENAME
//     Servant_Activator.cpp
//
// = DESCRIPTION
//     Implementation of Dir_Service_Activator , which is used by a
//     POA with a RETAIN policy.
//
// = AUTHOR
//     Kirthika Parameswaran <kirthika@cs.wustl.edu>
//
// ============================================================================

#include "Servant_Activator.h"
#include "Dir_Service_i.h"

ACE_RCSID(On_Demand_Loading, Servant_Activator, "$Id$")

// Initialization.

Dir_Service_Activator::Dir_Service_Activator (CORBA::ORB_ptr orb)
  :  orb_ (CORBA::ORB::_duplicate (orb))
{
}

// This method associates an seravnt with the ObjectID.

PortableServer::Servant
Dir_Service_Activator::incarnate (const PortableServer::ObjectId &oid,
                                  PortableServer::POA_ptr poa,
                                  CORBA::Environment &env)
{
  // Convert ObjectId to String.

  CORBA::String_var s = PortableServer::ObjectId_to_string (oid);

  // Activate and return the servant else exception.
  
  PortableServer::Servant servant = this->activate_servant (s.in (),
                                                            poa);

  if (servant != 0)
      return servant;
  else
    {
      // @@ Kirthika, can you please make this work for both
      // native and non-native C++ exceptions?  Please see
      // Nanbor if you have any questions.
      CORBA::Exception *exception = new CORBA::OBJECT_NOT_EXIST (CORBA::COMPLETED_NO);
      env.exception (exception);
      return 0;
    }
}

// This is the method is invoked when the object is deactivated or the
// entire POA is is deactivated or destroyed.

void
Dir_Service_Activator::etherealize (const PortableServer::ObjectId &oid,
                                    PortableServer::POA_ptr poa,
                                    PortableServer::Servant servant,
                                    CORBA::Boolean cleanup_in_progress,
                                    CORBA::Boolean remaining_activations,
                                    CORBA::Environment &env)
{
  ACE_UNUSED_ARG (oid);
  ACE_UNUSED_ARG (poa);
  ACE_UNUSED_ARG (cleanup_in_progress);
  ACE_UNUSED_ARG (env);

  // If there are no remaining activations i.e ObjectIds associated
  // with Dir_Service object deactivate it.

  if (remaining_activations == 0)
    deactivate_servant (servant);
}

// This method loads the dynamically linked library which is the
// servant and returns the servant object which is then used for other
// operations in the library.

PortableServer::Servant
Dir_Service_Activator::activate_servant (const char *str, 
                                         PortableServer::POA_ptr poa)
{
  // The string format is function@dll which needs to be parsed.
  parse_string (str);

  // Now that the library name is available we open the library.  @@
  // Kirthika, make SURE to check return values from function calls
  // like this and return failure results correctly...
  dll_.open (dllname_);

  // The next step is to obtain the symbol for the function that will
  // create the servant object and return it to us.
  Servant_Creator_Prototype servant_creator;
  servant_creator = (Servant_Creator_Prototype) dll_.symbol (create_symbol_.in ());
  
  // Checking whether it is possible to create the servant.
  if (servant_creator == 0)
    ACE_ERROR_RETURN ((LM_ERROR,
                       "%s",
                       dll_.error ()),
                      0);
   
  // Now create and return the servant.
  return this->servant_creator (this->orb_.in (), poa);
}

// This method removes the servant and the dll object associated with
// it with performed the opening and symbol obtaining operations.
 
void 
Dir_Service_Activator::deactivate_servant (PortableServer::Servant servant)
{
  // the servant is destroyed.
  delete servant;
}

// The objectID is in a format of library:factory_method which has to
// be parsed and separated into tokens to be used.

void
Dir_Service_Activator::parse_string (const char *s)
{
  // The format of the object library:factory_method.  This string is
  // parsed to obatin the library name and the function name which
  // will create trhe servant and return it to us.

  char str[BUFSIZ],func[BUFSIZ], libname [BUFSIZ];
  char at[2];

  at[0]= ':';
  at[1]= '\0';
  // @@ Kirthika, please use the ACE_OS::str*() functions
  // consistently.
  strcpy (func, "");
  // As strtok () puts a NULL in the position after it gives back a
  // token, we make two copies of the input string.
  strcpy (str, s);

  // @@ Kirthika, this comment is out of date.
  // The strtok() method returns the string until '@' i.e. the
  // function name.
  ACE_OS::strcpy (libname, ACE_OS::strtok (str, at));
   
  // Get to ':' and make the libname point to the next location in the
  // string.
  ACE_OS::strcpy (func, ACE_OS::strchr (s,':') + 1);
  
  // Assign the respective strings obtained.

  this->dllname_ = CORBA::string_dup (libname);
  this->create_symbol_ = CORBA::string_dup (func);

  ACE_DEBUG ((LM_DEBUG,
              "the servant library:%s\n the factory_method:%s\n ", 
              this->dllname_.in (),
              this->create_symbol_.in ()));
}