OmniEvents
|
00001 // Package : omniEvents 00002 // Orb.cc Created : 2003/12/04 00003 // Author : Alex Tingle 00004 // 00005 // Copyright (C) 2003-2005 Alex Tingle. 00006 // 00007 // This file is part of the omniEvents application. 00008 // 00009 // omniEvents is free software; you can redistribute it and/or 00010 // modify it under the terms of the GNU Lesser General Public 00011 // License as published by the Free Software Foundation; either 00012 // version 2.1 of the License, or (at your option) any later version. 00013 // 00014 // omniEvents is distributed in the hope that it will be useful, 00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 // Lesser General Public License for more details. 00018 // 00019 // You should have received a copy of the GNU Lesser General Public 00020 // License along with this library; if not, write to the Free Software 00021 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 // 00023 00024 #include "Orb.h" 00025 00026 #ifdef HAVE_IOSTREAM 00027 # include <iostream> 00028 #else 00029 # include <iostream.h> 00030 #endif 00031 00032 #include <stdlib.h> 00033 #include <assert.h> 00034 00035 #include "Callback.h" 00036 00037 namespace OmniEvents { 00038 00039 Orb Orb::_inst; 00040 00041 00042 Orb::~Orb() 00043 { 00044 omni_mutex_lock l(_deferredRequestsLock); 00045 list<RequestCallback_t>::iterator curr, next=_deferredRequests.begin(); 00046 while(next!=_deferredRequests.end()) 00047 { 00048 curr=next++; 00049 CORBA::release(curr->first); 00050 _deferredRequests.erase(curr); 00051 } 00052 } 00053 00054 00055 void Orb::resolveInitialReferences() 00056 { 00057 assert(!CORBA::is_nil(_orb)); 00058 00059 const char* action=""; // Use this variable to help report errors. 00060 try 00061 { 00062 CORBA::Object_var obj; 00063 00064 action="resolve initial reference 'RootPOA'"; 00065 obj=_orb->resolve_initial_references("RootPOA"); 00066 _RootPOA=PortableServer::POA::_narrow(obj); 00067 if(CORBA::is_nil(_RootPOA)) 00068 throw CORBA::OBJECT_NOT_EXIST(); 00069 00070 action="resolve initial reference 'omniINSPOA'"; 00071 obj=_orb->resolve_initial_references("omniINSPOA"); 00072 _omniINSPOA=PortableServer::POA::_narrow(obj); 00073 if(CORBA::is_nil(_omniINSPOA)) 00074 throw CORBA::OBJECT_NOT_EXIST(); 00075 00076 // The naming service is optional. 00077 try 00078 { 00079 action="resolve initial reference 'NameService'"; 00080 obj=_orb->resolve_initial_references("NameService"); 00081 _NameService=CosNaming::NamingContext::_narrow(obj); 00082 } 00083 catch(CORBA::Exception& ex) 00084 { 00085 DB(1,"Warning - failed to "<<action<< 00086 IFELSE_OMNIORB4(". Exception: "<<ex._name(),".")) 00087 } 00088 00089 #ifdef HAVE_OMNIORB4 00090 action="resolve initial reference 'POACurrent'"; 00091 obj=_orb->resolve_initial_references("POACurrent"); 00092 _POACurrent=PortableServer::Current::_narrow(obj); 00093 if(CORBA::is_nil(_POACurrent)) 00094 throw CORBA::OBJECT_NOT_EXIST(); 00095 #endif 00096 00097 return; 00098 } 00099 catch(CORBA::ORB::InvalidName& ex) // resolve_initial_references 00100 { 00101 DB(0,"Failed to "<<action<<". InvalidName") 00102 } 00103 catch(CORBA::TRANSIENT& ex) // _narrow() 00104 { 00105 DB(0,"Failed to "<<action<<". TRANSIENT") 00106 } 00107 catch(CORBA::OBJECT_NOT_EXIST& ex) // _narrow() 00108 { 00109 DB(0,"Failed to "<<action<<". OBJECT_NOT_EXIST") 00110 } 00111 catch(CORBA::SystemException& ex) 00112 { 00113 DB(0,"Failed to "<<action<<"." 00114 IF_OMNIORB4(" "<<ex._name()<<" ("<<NP_MINORSTRING(ex)<<")") ) 00115 } 00116 catch(CORBA::Exception& ex) 00117 { 00118 DB(0,"Failed to "<<action<<"." IF_OMNIORB4(" "<<ex._name()) ) 00119 } 00120 exit(1); 00121 } 00122 00123 00124 void Orb::run() 00125 { 00126 while(!_shutdownRequested) 00127 { 00128 omni_thread::sleep(5); 00129 00130 list<Callback*> usedCallbacks; 00131 { 00132 omni_mutex_lock l(_deferredRequestsLock); 00133 DB(20,"Polling "<<_deferredRequests.size()<<" deferred requests.") 00134 list<RequestCallback_t>::iterator curr, next=_deferredRequests.begin(); 00135 while(next!=_deferredRequests.end()) 00136 { 00137 curr=next++; 00138 if(curr->first->poll_response()) 00139 { 00140 CORBA::Environment_ptr env=curr->first->env();// No need to release. 00141 if(!CORBA::is_nil(env) && env->exception()) 00142 { 00143 CORBA::Exception* ex =env->exception(); // No need to free exception 00144 DB(10,"Deferred call to "<<curr->first->operation() 00145 <<"() got exception" IF_OMNIORB4(<<": "<<ex->_name())) 00146 } 00147 else if(curr->second) 00148 { 00149 DB(15,"Deferred call to "<<curr->first->operation()<<"() returned.") 00150 curr->second->callback(curr->first); 00151 } 00152 else 00153 { 00154 DB(15,"Orphan call to "<<curr->first->operation()<<"() returned.") 00155 } 00156 CORBA::release(curr->first); 00157 if(curr->second) 00158 usedCallbacks.push_back( curr->second ); 00159 _deferredRequests.erase(curr); 00160 } 00161 } // end loop while() 00162 } 00163 // _deferredRequestsLock is now unlocked: clear away used callbacks. 00164 // (Cannot do this while _deferredRequestsLock is held, because of the 00165 // following deadlock: 00166 // _remove_ref() -> ~Proxy() -> Orb::deferredRequest() 00167 while(!usedCallbacks.empty()) 00168 { 00169 usedCallbacks.front()->_remove_ref(); 00170 usedCallbacks.pop_front(); 00171 } 00172 } // end loop while(!_shutdownRequested) 00173 00174 // Clean up all outstanding requests. 00175 omni_mutex_lock l(_deferredRequestsLock); 00176 while(!_deferredRequests.empty()) 00177 { 00178 _deferredRequests.front().first->get_response(); 00179 CORBA::release(_deferredRequests.front().first); 00180 if(_deferredRequests.front().second) 00181 _deferredRequests.front().second->_remove_ref(); 00182 _deferredRequests.pop_front(); 00183 } 00184 } 00185 00186 00187 void Orb::deferredRequest(CORBA::Request_ptr req, Callback* callback) 00188 { 00189 if(_shutdownRequested) 00190 callback=NULL; 00191 // If _shutdownRequested and Orb::run() has already terminated, then 00192 // the request (req) will never be collected or released. This is sad, and it 00193 // makes omniORB complain - but at least it works: 00194 // Attempting to get_response() here can cause deadlock. Just releasing the 00195 // Request causes a SEGV when the call returns. 00196 00197 if(callback) 00198 callback->_add_ref(); 00199 omni_mutex_lock l(_deferredRequestsLock); 00200 _deferredRequests.push_back(RequestCallback_t(req,callback)); 00201 } 00202 00203 00204 void Orb::reportObjectFailure( 00205 const char* here, 00206 CORBA::Object_ptr obj, 00207 CORBA::Exception* ex 00208 ) 00209 { 00210 assert(!CORBA::is_nil(obj)); 00211 #ifdef HAVE_OMNIORB4 00212 { 00213 // Hack! The '!' signals object failure. 00214 // See DaemonImpl::log() in daemon_unix.cc. 00215 omniORB::logger log("omniEvents! Object failure: "); 00216 omniIOR* ior =obj->_PR_getobj()->_getIOR(); 00217 // Log Repository ID. 00218 log<<ior->repositoryID(); 00219 // Log Object ID. (Limitation: only display the first TAG_INTERNET_IOP) 00220 for(CORBA::ULong i=0; i<ior->iopProfiles().length(); i++) 00221 { 00222 if (ior->iopProfiles()[i].tag == IOP::TAG_INTERNET_IOP) 00223 { 00224 IIOP::ProfileBody pBody; 00225 IIOP::unmarshalProfile(ior->iopProfiles()[i],pBody); 00226 log<<" \""; 00227 for(CORBA::ULong j=0; j<pBody.object_key.length(); ++j) 00228 { 00229 char c=(char)pBody.object_key[j]; 00230 log<<( (c>=' '&&c<='~')? c: '.' ); // Log object key as text 00231 } 00232 log<<"\" at "<<(const char*)pBody.address.host<<":"<<pBody.address.port; 00233 break; // ONLY DISPLAY FIRST! 00234 } 00235 } 00236 // Log exception. 00237 if(!ex) 00238 { 00239 log<<" threw unknown exception\n"; 00240 } 00241 else 00242 { 00243 log<<" threw "<<ex->_name(); 00244 CORBA::SystemException* sysex =CORBA::SystemException::_downcast(ex); 00245 if(sysex) 00246 log<<" ("<<NP_MINORSTRING(*sysex)<<")"; 00247 log<<"\n"; 00248 } 00249 } 00250 #endif 00251 { 00252 omniORB::logger log("omniEvents! Object failure detail: "); 00253 CORBA::String_var sior( Orb::inst()._orb->object_to_string(obj) ); 00254 log<<sior<<" at "<<here<<"\n"; 00255 } 00256 } 00257 00258 00259 }; // end namespace OmniEvents