object deactivation

Sai-Lai Lo S.Lo@orl.co.uk
Thu, 17 Jul 1997 14:05:21 +0100


>>>>> Matthew Newhook writes:

>   There doesn't seem to be any way of releasing an implementation object
>   in a application without releasing all references to that object
>   within the same application.  This is quite a problem.  I would
>   expect to be able to tell the ORB that the object is no longer
>   active, and then delete the implementation object.  Any further calls
>   to that object would result either in a TRANSIENT or OBJECT_NOT_EXIST
>   exception, until the object is reactivated.

>   Any ideas on how to proceed in this area?

Your description is correct and is documented in the omniORB2 user's guide
(2.7.4 Object disposal). 

To obtain the behaviour your want, an additional level of indirection is
needed.

Essentially the real implementation cannot directly inherits from the
implementation skeleton. Instead, a new class has to be introduced to link
between the skeleton and the real implementation.

I shall use the Echo example to illustrate how I think one should proceed:
The example only shows how one can implement _dispose() that will guarantee
to have called the dtor of the real implementation when it returns. Further
calls to the object, local or remote would result in OBJECT_NOT_EXIST
exception. The principle is the same to implement an object that can be
reactivated, only the details differ.


// Real implmentation of echo
class Echo_realImpl {
public:
   char* echoString(const char* mesg);
};

class Echo_i : public _sk_Echo {
public:

   Echo_i(Echo_realImpl* p) : realImpl_ptr(p), 
                              _v(&m), 
                              _is_disposed(0),
                              _n_concurrency(0) {}

   char* echoString(const char*mesg) {
       assertObjIsReady _a;
       return realImpl_ptr->echoString(mesg);
   }

   void _dispose() {
      _m.lock();
      if (!_is_disposed) {
         _is_disposed = 1;
         while (_n_concurrency) {
            _v.wait();
         }
         delete realImpl_ptr;
         _m.unlock();
         _sk_Echo::_dispose();
      }
      else {
        _m.unlock();
      }
      return;
   }

private:
   Echo_realImpl* realImpl_ptr;
   omni_mutex      _m;
   omni_condition  _v;
   CORBA::Boolean  _is_disposed;
   CORBA::ULong    _n_concurrency;

   class assertObjIsReady {
   public:
      assertObjIsReady() {
        _m.lock();
        if (_is_disposed) {
           _m.unlock();
           throw CORBA::OBJECT_NOT_EXIST(0,CORBA::COMPLETED_NO);
        }
        else {
           _n_concurrency++;
           _m.unlock();
        }
     }
     ~assertObjIsReady() {
        _m.lock();
        _n_concurrency--;
        if (_is_disposed) {
	   _v.signal();
	}
        _m.unlock();
     }
   };

  Echo_i();  // Do not allow the use of default ctor
};