CORBA-omniORB

 view release on metacpan or  search on metacpan

pomni.h  view on Meta::CPAN


//-------------------------------------------------------------------
void cm_log( const char* format, ... );
#ifdef NDEBUG
#define CM_DEBUG(v)
#else
#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_;



( run in 1.112 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )