Index: doc/tex/omniORB.tex =================================================================== --- doc/tex/omniORB.tex (revision 5915) +++ doc/tex/omniORB.tex (working copy) @@ -5348,7 +5348,18 @@ chaining is performed by calls through the \op{info\_T::run} method, rather than by visiting interceptor functions in turn. +\item[signalMainThread]\mbox{}\\ +% +Called when the ORB signals the main thread to inform it that work is +available (i.e. an incoming request) for a servant activated by a +POA implementing the MAIN\_THREAD\_MODEL policy. The interceptor +function must call the \op{info\_T::run} method to actually trigger +the signalling. +The application can use this interceptor to integrate single-threaded +servants into a foreign event-loop by marshalling an event after +\op{run} has finished and calling the \op{ORB::perform\_work} method +in the dispatcher. \end{description} Index: include/omniORB4/internal/interceptors.h =================================================================== --- include/omniORB4/internal/interceptors.h (revision 5915) +++ include/omniORB4/internal/interceptors.h (working copy) @@ -83,6 +83,7 @@ static _core_attr elmT* createPolicy; static _core_attr elmT* createThread; static _core_attr elmT* assignUpcallThread; + static _core_attr elmT* signalMainThread; #define VISIT_FUNCTION(name) \ static inline void visit(omniInterceptors::name##_T::info_T& info) { \ Index: include/omniORB4/omniInterceptors.h =================================================================== --- include/omniORB4/omniInterceptors.h (revision 5915) +++ include/omniORB4/omniInterceptors.h (working copy) @@ -350,7 +350,21 @@ void remove(interceptFunc); }; + ////////////////////////////////////////////////////////////////// + class signalMainThread_T { + public: + + class info_T { + public: + virtual void run() = 0; + }; + typedef void (*interceptFunc)(info_T& info); + + void add(interceptFunc); + void remove(interceptFunc); + }; + ////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// encodeIOR_T encodeIOR; @@ -365,6 +379,7 @@ createPolicy_T createPolicy; createThread_T createThread; assignUpcallThread_T assignUpcallThread; + signalMainThread_T signalMainThread; ////////////////////////////////////////////////////////////////// friend class omni_interceptor_initialiser; Index: src/lib/omniORB/orbcore/corbaOrb.cc =================================================================== --- src/lib/omniORB/orbcore/corbaOrb.cc (revision 5915) +++ src/lib/omniORB/orbcore/corbaOrb.cc (working copy) @@ -364,6 +364,8 @@ #include #include #include +#include +#include #ifdef HAVE_SIGNAL_H # include @@ -697,6 +699,41 @@ return the_orb; } +OMNI_NAMESPACE_BEGIN(omni) + +class signalInfo + : public omniInterceptors::signalMainThread_T::info_T { +public: + signalInfo(omni_tracedcondition& cv, bool broadcast) : + pd_cv(cv), pd_broadcast(broadcast), pd_elmt(omniInterceptorP::signalMainThread) {} + + void run(); + +private: + omni_tracedcondition& pd_cv; + bool pd_broadcast; + omniInterceptorP::elmT* pd_elmt; +}; + +void +signalInfo::run() +{ + if (pd_elmt) { + omniInterceptors::signalMainThread_T::interceptFunc f = + (omniInterceptors::signalMainThread_T::interceptFunc)pd_elmt->func; + pd_elmt = pd_elmt->next; + f(*this); + } else { + if (pd_broadcast) + pd_cv.broadcast(); + else + pd_cv.signal(); + } +} + +OMNI_NAMESPACE_END(omni) + + ////////////////////////////////////////////////////////////////////// ///////////////////////////// omniOrbORB ///////////////////////////// ////////////////////////////////////////////////////////////////////// @@ -1121,7 +1158,10 @@ if (invoker_signal.timedwait(secs, nanosecs) == 0) { // timeout invoker_threads--; - if (invoker_shutting_down) invoker_signal.signal(); + if (invoker_shutting_down) { + signalInfo info(invoker_signal, false); + info.run(); + } orb_lock.unlock(); return; } @@ -1148,7 +1188,10 @@ OMNIORB_ASSERT(omniTaskLink::is_empty(invoker_dedicated_tq)); invoker_threads--; - if (invoker_shutting_down) invoker_signal.signal(); + if (invoker_shutting_down) { + signalInfo info(invoker_signal, false); + info.run(); + } orb_lock.unlock(); } @@ -1159,7 +1202,8 @@ omni_tracedmutex_lock sync(orb_lock); t->enq(invoker_dedicated_tq); - invoker_signal.signal(); + signalInfo info(invoker_signal, false); + info.run(); return 1; } @@ -1190,7 +1234,8 @@ { ASSERT_OMNI_TRACEDMUTEX_HELD(orb_lock, 1); invoker_shutting_down = 1; - invoker_signal.broadcast(); + signalInfo info(invoker_signal, true); + info.run(); } Index: src/lib/omniORB/orbcore/interceptors.cc =================================================================== --- src/lib/omniORB/orbcore/interceptors.cc (revision 5915) +++ src/lib/omniORB/orbcore/interceptors.cc (working copy) @@ -86,6 +86,7 @@ omniInterceptorP::elmT* omniInterceptorP::createPolicy = 0; omniInterceptorP::elmT* omniInterceptorP::createThread = 0; omniInterceptorP::elmT* omniInterceptorP::assignUpcallThread = 0; +omniInterceptorP::elmT* omniInterceptorP::signalMainThread = 0; static void list_add(omniInterceptorP::elmT** ep, void* func) @@ -146,6 +147,7 @@ INTERCEPTOR_IMPLEMENTATION(createPolicy) INTERCEPTOR_IMPLEMENTATION(createThread) INTERCEPTOR_IMPLEMENTATION(assignUpcallThread) +INTERCEPTOR_IMPLEMENTATION(signalMainThread) #undef INTERCEPTOR_IMPLEMENTATION @@ -178,6 +180,7 @@ list_del(&omniInterceptorP::createPolicy); list_del(&omniInterceptorP::createThread); list_del(&omniInterceptorP::assignUpcallThread); + list_del(&omniInterceptorP::signalMainThread); } }