CORBA-omniORB
view release on metacpan or search on metacpan
#define CM_DEBUG(v) cm_log v
#endif
//-------------------------------------------------------------------
// C++-friendly croak()
// Trampoline classes
class POmniCroak {
public:
POmniCroak(pTHX_ const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
SV *errsv = get_sv("@", TRUE);
sv_vsetpvf(errsv, fmt, &ap);
va_end(ap);
}
};
class POmniThrowable {
SV *e_;
public:
POmniThrowable(SV *e)
: e_(e) {
}
SV *exception_object(void) {
return e_;
}
};
#define CATCH_POMNI_TRAMPOLINE \
catch (POmniCroak) { \
croak(Nullch); \
} \
catch (POmniThrowable &throwable) { \
pomni_throw(aTHX_ throwable.exception_object()); \
}
#define CATCH_POMNI_SYSTEMEXCEPTION \
catch (CORBA::SystemException &sysex) { \
pomni_throw(aTHX_ pomni_system_except(aTHX_ \
sysex._rep_id(), \
sysex.minor(), \
sysex.completed())); \
}
//-------------------------------------------------------------------
/** Mutex to serialize servant calls from omniORB. Allows the mutex
* to be temporarily released to allow callbacks with a deeper
* recursion level to execute.
*/
class POmniRatchetLock {
omni_mutex mutex_;
volatile bool locked_;
omni_condition entry_cond_;
volatile unsigned awaiting_entry_;
struct Entry {
bool waiting;
omni_condition *cond;
Entry(omni_mutex *mutex)
: waiting(false), cond(new omni_condition(mutex)) {
}
};
typedef std::vector<Entry> _T;
_T stack_;
_T::iterator top_; // Stack top
inline void grow() {
_T::size_type top = top_ - stack_.begin();
stack_.push_back(Entry(&mutex_)); // Invalidates iterators
top_ = stack_.begin() + top;
}
public:
POmniRatchetLock(void)
: locked_(true),
entry_cond_(&mutex_),
awaiting_entry_(0),
top_(stack_.begin()) {
grow(); // initial entry
}
~POmniRatchetLock(void) {
for(_T::iterator i = stack_.begin(); i != stack_.end(); ++i) {
delete i->cond;
}
}
//! Enter a new recursion level.
void enter(void) {
mutex_.lock();
++awaiting_entry_;
while(locked_)
entry_cond_.wait();
--awaiting_entry_;
++top_;
if(top_ == stack_.end())
grow();
locked_ = true;
mutex_.unlock();
}
//! Exit the current recursion level.
void leave(void) {
mutex_.lock();
locked_ = false;
--top_;
if(awaiting_entry_ > 0)
entry_cond_.signal();
else if(top_->waiting)
top_->cond->signal();
mutex_.unlock();
}
//! Token used to indicate the current recursion level for later
// resumption.
typedef _T::size_type token;
//! Release the lock for use by deeper recursion levels.
token release(void) {
mutex_.lock();
locked_ = false;
if(awaiting_entry_ > 0)
entry_cond_.signal();
token t = top_ - stack_.begin();
mutex_.unlock();
return t;
}
//! Resume the specified recursion level.
void resume(token t) {
mutex_.lock();
_T::iterator ti = stack_.begin() + t;
ti->waiting = true;
while(locked_ || ti != top_) {
ti->cond->wait();
ti = stack_.begin() + t;
}
ti->waiting = false;
locked_ = true;
mutex_.unlock();
}
};
// Return the entry lock for the current Perl interpreter
POmniRatchetLock *pomni_entry_lock(pTHX);
/** Object to temporarily unlock the Perl interpreter during a blocking
* operation, allowing other threads to make use of the interpreter.
* Usage should follow the pattern:
*
* PUTBACK;
* {
* POmniPerlEntryUnlocker ul(aTHX);
* <some potentially blocking operation>
* }
* SPAGAIN;
*/
class POmniPerlEntryUnlocker {
POmniRatchetLock *entry_lock_;
POmniRatchetLock::token t_;
public:
POmniPerlEntryUnlocker(pTHX)
: entry_lock_(pomni_entry_lock(aTHX)),
t_(entry_lock_ ? entry_lock_->release() : 0) {
}
~POmniPerlEntryUnlocker(void) {
if (entry_lock_)
entry_lock_->resume(t_);
}
};
/*!
* ORB instance
*/
extern CORBA::ORB_ptr pomni_orb;
( run in 1.280 second using v1.01-cache-2.11-cpan-5c0b1e786e0 )