OmniEvents
Orb.cc
Go to the documentation of this file.
1// Package : omniEvents
2// Orb.cc Created : 2003/12/04
3// Author : Alex Tingle
4//
5// Copyright (C) 2003-2005 Alex Tingle.
6//
7// This file is part of the omniEvents application.
8//
9// omniEvents is free software; you can redistribute it and/or
10// modify it under the terms of the GNU Lesser General Public
11// License as published by the Free Software Foundation; either
12// version 2.1 of the License, or (at your option) any later version.
13//
14// omniEvents is distributed in the hope that it will be useful,
15// but WITHOUT ANY WARRANTY; without even the implied warranty of
16// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17// Lesser General Public License for more details.
18//
19// You should have received a copy of the GNU Lesser General Public
20// License along with this library; if not, write to the Free Software
21// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22//
23
24#include "Orb.h"
25
26#ifdef HAVE_IOSTREAM
27# include <iostream>
28#else
29# include <iostream.h>
30#endif
31
32#include <stdlib.h>
33#include <assert.h>
34
35#include "Callback.h"
36
37namespace OmniEvents {
38
39Orb Orb::_inst;
40
41
43{
44 omni_mutex_lock l(_deferredRequestsLock);
45 list<RequestCallback_t>::iterator curr, next=_deferredRequests.begin();
46 while(next!=_deferredRequests.end())
47 {
48 curr=next++;
49 CORBA::release(curr->first);
50 _deferredRequests.erase(curr);
51 }
52}
53
54
56{
57 assert(!CORBA::is_nil(_orb));
58
59 const char* action=""; // Use this variable to help report errors.
60 try
61 {
62 CORBA::Object_var obj;
63
64 action="resolve initial reference 'RootPOA'";
65 obj=_orb->resolve_initial_references("RootPOA");
66 _RootPOA=PortableServer::POA::_narrow(obj);
67 if(CORBA::is_nil(_RootPOA))
68 throw CORBA::OBJECT_NOT_EXIST();
69
70 action="resolve initial reference 'omniINSPOA'";
71 obj=_orb->resolve_initial_references("omniINSPOA");
72 _omniINSPOA=PortableServer::POA::_narrow(obj);
73 if(CORBA::is_nil(_omniINSPOA))
74 throw CORBA::OBJECT_NOT_EXIST();
75
76 // The naming service is optional.
77 try
78 {
79 action="resolve initial reference 'NameService'";
80 obj=_orb->resolve_initial_references("NameService");
81 _NameService=CosNaming::NamingContext::_narrow(obj);
82 }
83 catch(CORBA::Exception& ex)
84 {
85 DB(1,"Warning - failed to "<<action<<
86 IFELSE_OMNIORB4(". Exception: "<<ex._name(),"."))
87 }
88
89#ifdef HAVE_OMNIORB4
90 action="resolve initial reference 'POACurrent'";
91 obj=_orb->resolve_initial_references("POACurrent");
92 _POACurrent=PortableServer::Current::_narrow(obj);
93 if(CORBA::is_nil(_POACurrent))
94 throw CORBA::OBJECT_NOT_EXIST();
95#endif
96
97 return;
98 }
99 catch(CORBA::ORB::InvalidName& ex) // resolve_initial_references
100 {
101 DB(0,"Failed to "<<action<<". InvalidName")
102 }
103 catch(CORBA::TRANSIENT& ex) // _narrow()
104 {
105 DB(0,"Failed to "<<action<<". TRANSIENT")
106 }
107 catch(CORBA::OBJECT_NOT_EXIST& ex) // _narrow()
108 {
109 DB(0,"Failed to "<<action<<". OBJECT_NOT_EXIST")
110 }
111 catch(CORBA::SystemException& ex)
112 {
113 DB(0,"Failed to "<<action<<"."
114 IF_OMNIORB4(" "<<ex._name()<<" ("<<NP_MINORSTRING(ex)<<")") )
115 }
116 catch(CORBA::Exception& ex)
117 {
118 DB(0,"Failed to "<<action<<"." IF_OMNIORB4(" "<<ex._name()) )
119 }
120 exit(1);
121}
122
123
125{
126 while(!_shutdownRequested)
127 {
128 omni_thread::sleep(5);
129
130 list<Callback*> usedCallbacks;
131 {
132 omni_mutex_lock l(_deferredRequestsLock);
133 DB(20,"Polling "<<_deferredRequests.size()<<" deferred requests.")
134 list<RequestCallback_t>::iterator curr, next=_deferredRequests.begin();
135 while(next!=_deferredRequests.end())
136 {
137 curr=next++;
138 if(curr->first->poll_response())
139 {
140 CORBA::Environment_ptr env=curr->first->env();// No need to release.
141 if(!CORBA::is_nil(env) && env->exception())
142 {
143 CORBA::Exception* ex =env->exception(); // No need to free exception
144 DB(10,"Deferred call to "<<curr->first->operation()
145 <<"() got exception" IF_OMNIORB4(<<": "<<ex->_name()))
146 }
147 else if(curr->second)
148 {
149 DB(15,"Deferred call to "<<curr->first->operation()<<"() returned.")
150 curr->second->callback(curr->first);
151 }
152 else
153 {
154 DB(15,"Orphan call to "<<curr->first->operation()<<"() returned.")
155 }
156 CORBA::release(curr->first);
157 if(curr->second)
158 usedCallbacks.push_back( curr->second );
159 _deferredRequests.erase(curr);
160 }
161 } // end loop while()
162 }
163 // _deferredRequestsLock is now unlocked: clear away used callbacks.
164 // (Cannot do this while _deferredRequestsLock is held, because of the
165 // following deadlock:
166 // _remove_ref() -> ~Proxy() -> Orb::deferredRequest()
167 while(!usedCallbacks.empty())
168 {
169 usedCallbacks.front()->_remove_ref();
170 usedCallbacks.pop_front();
171 }
172 } // end loop while(!_shutdownRequested)
173
174 // Clean up all outstanding requests.
175 omni_mutex_lock l(_deferredRequestsLock);
176 while(!_deferredRequests.empty())
177 {
178 _deferredRequests.front().first->get_response();
179 CORBA::release(_deferredRequests.front().first);
180 if(_deferredRequests.front().second)
181 _deferredRequests.front().second->_remove_ref();
182 _deferredRequests.pop_front();
183 }
184}
185
186
187void Orb::deferredRequest(CORBA::Request_ptr req, Callback* callback)
188{
190 callback=NULL;
191 // If _shutdownRequested and Orb::run() has already terminated, then
192 // the request (req) will never be collected or released. This is sad, and it
193 // makes omniORB complain - but at least it works:
194 // Attempting to get_response() here can cause deadlock. Just releasing the
195 // Request causes a SEGV when the call returns.
196
197 if(callback)
198 callback->_add_ref();
199 omni_mutex_lock l(_deferredRequestsLock);
200 _deferredRequests.push_back(RequestCallback_t(req,callback));
201}
202
203
205 const char* here,
206 CORBA::Object_ptr obj,
207 CORBA::Exception* ex
208)
209{
210 assert(!CORBA::is_nil(obj));
211#ifdef HAVE_OMNIORB4
212 {
213 // Hack! The '!' signals object failure.
214 // See DaemonImpl::log() in daemon_unix.cc.
215 omniORB::logger log("omniEvents! Object failure: ");
216 omniIOR* ior =obj->_PR_getobj()->_getIOR();
217 // Log Repository ID.
218 log<<ior->repositoryID();
219 // Log Object ID. (Limitation: only display the first TAG_INTERNET_IOP)
220 for(CORBA::ULong i=0; i<ior->iopProfiles().length(); i++)
221 {
222 if (ior->iopProfiles()[i].tag == IOP::TAG_INTERNET_IOP)
223 {
224 IIOP::ProfileBody pBody;
225 IIOP::unmarshalProfile(ior->iopProfiles()[i],pBody);
226 log<<" \"";
227 for(CORBA::ULong j=0; j<pBody.object_key.length(); ++j)
228 {
229 char c=(char)pBody.object_key[j];
230 log<<( (c>=' '&&c<='~')? c: '.' ); // Log object key as text
231 }
232 log<<"\" at "<<(const char*)pBody.address.host<<":"<<pBody.address.port;
233 break; // ONLY DISPLAY FIRST!
234 }
235 }
236 // Log exception.
237 if(!ex)
238 {
239 log<<" threw unknown exception\n";
240 }
241 else
242 {
243 log<<" threw "<<ex->_name();
244 CORBA::SystemException* sysex =CORBA::SystemException::_downcast(ex);
245 if(sysex)
246 log<<" ("<<NP_MINORSTRING(*sysex)<<")";
247 log<<"\n";
248 }
249 }
250#endif
251 {
252 omniORB::logger log("omniEvents! Object failure detail: ");
253 CORBA::String_var sior( Orb::inst()._orb->object_to_string(obj) );
254 log<<sior<<" at "<<here<<"\n";
255 }
256}
257
258
259}; // end namespace OmniEvents
#define IFELSE_OMNIORB4(omniORB4_code, default_code)
Definition Orb.h:45
#define DB(l, x)
Definition Orb.h:49
#define IF_OMNIORB4(omniORB4_code)
Definition Orb.h:46
#define NP_MINORSTRING(systemException)
Definition Orb.h:52
Interface for classes that wish to receive callbacks from deferred requests.
Definition Callback.h:46
PortableServer::POA_var _RootPOA
Definition Orb.h:89
pair< CORBA::Request_ptr, Callback * > RequestCallback_t
Definition Orb.h:73
~Orb()
Destructor needs to be public to keep MS VC++6 happy.
Definition Orb.cc:42
list< RequestCallback_t > _deferredRequests
Definition Orb.h:74
CORBA::ORB_var _orb
Definition Orb.h:88
static Orb _inst
Definition Orb.h:72
bool _shutdownRequested
Definition Orb.h:76
CosNaming::NamingContext_var _NameService
Definition Orb.h:91
void deferredRequest(CORBA::Request_ptr req, Callback *callback=NULL)
Adopts the request and then stores it in _deferredRequests.
Definition Orb.cc:187
void reportObjectFailure(const char *here, CORBA::Object_ptr obj, CORBA::Exception *ex)
Called by omniEvents when an object has failed (fatal exception).
Definition Orb.cc:204
void resolveInitialReferences()
_orb must already have been initialized before this method is called.
Definition Orb.cc:55
static Orb & inst()
Definition Orb.h:81
omni_mutex _deferredRequestsLock
Definition Orb.h:75
void run()
Parks the main thread, but also picks up (and ignores) responses from orphan requests.
Definition Orb.cc:124
PortableServer::POA_var _omniINSPOA
Definition Orb.h:90