/afs/cern.ch/user/k/kolos/working/online/ipc/ipc/object.h

Go to the documentation of this file.
00001 #ifndef IPC_OBJECT_H
00002 #define IPC_OBJECT_H
00003 
00005 //      servant.h
00006 //
00007 //      header file for the IPC library
00008 //
00009 //      Sergei Kolos, June 2003
00010 //
00011 //      description:
00012 //        IPCObject - base class for the servants passed by reference
00013 //        IPCNamedObject - base class for the servants published
00014 //                         in the IPCPartition
00016 #include <string>
00017 #include <sstream>
00018 #include <iostream>
00019 
00020 #include <owl/time.h>
00021 #include <owl/semaphore.h>
00022 
00023 #include <ipc/objectadapter.h>
00024 #include <ipc/partition.h>
00025 #include <ipc/servant.h>
00026 
00038 template <class T>
00039 class IPCObjectBase :   public virtual T,
00040                         public virtual PortableServer::RefCountServantBase
00041 {  
00042   public:
00043       
00044     virtual ~IPCObjectBase ( ) {
00045         ERS_ASSERT_MSG( !active_,
00046                         "the IPCObjectBase destructor is called, but the corresponding servant is still active\n" <<
00047                         "to fix the problem you have to respect the following rules:\n" <<
00048                         "    1. Always allocate your IPC based objects in the heap using the new operator\n" <<
00049                         "    2. Always use the _destroy() method instead of the delete operator" )
00050         if ( sem_ ) {
00051             sem_ -> post();
00052         }
00053     }
00054         
00063     void _destroy( bool wait_for_completion = false )
00064     {
00065         if ( active_ ) {
00066             adapter_.remove( this );
00067             active_ = false;
00068         }
00069         
00070         if ( wait_for_completion ) {
00071             OWLSemaphore * semaphore = sem_;
00072             _remove_ref();
00073             semaphore -> wait();
00074             delete semaphore;
00075         }
00076         else {
00077             delete sem_;
00078             sem_ = 0;
00079             _remove_ref();
00080         }
00081     }
00082     
00083   protected:
00084      IPCObjectBase ( bool threaded )
00085       : adapter_( this, threaded ),
00086         active_( false )
00087     { sem_ = new OWLSemaphore(); }
00088     
00089     IPCObjectBase ( const IPCObjectBase * s ) 
00090       : adapter_( s->adapter_ ),
00091         active_( false )
00092     { sem_ = new OWLSemaphore(); }
00093 
00094    
00095     PortableServer::POA_ptr _default_POA() {
00096         activate();
00097         return adapter_;
00098     }
00099     
00100     void activate() {
00101         if ( !active_ ) {
00102             adapter_.add( this, oid() );
00103             active_ = true;
00104         }
00105     }
00106     
00107     virtual const std::string & oid() const = 0;
00108     
00109   private:      
00111     // Disable copying
00113     IPCObjectBase ( const IPCObjectBase & );
00114     IPCObjectBase & operator=( const IPCObjectBase & );
00115     
00116     IPCObjectAdapter    adapter_;
00117     bool                active_;
00118     OWLSemaphore *      sem_;
00119 };
00120 
00125 template <class T>
00126 class IPCObjectOperations : public IPCObjectBase<T>
00127 {
00128     std::string name_;
00129     const std::string & oid() const { return name_; }
00130     
00131   protected:
00132     IPCObjectOperations( bool threaded )
00133       : IPCObjectBase<T>( threaded ) {
00134         std::ostringstream out;
00135         out << this;
00136         name_ = out.str();
00137     }
00138     
00139     IPCObjectOperations( const IPCObjectOperations * op )
00140       : IPCObjectBase<T>( op ) {
00141         std::ostringstream out;
00142         out << this;
00143         name_ = out.str();
00144     }
00145 };
00146 
00171 template <class T, class TP = ipc::multi_thread>
00172 class IPCObject : public IPCObjectOperations<T>
00173 {  
00174   public:
00175       
00176     virtual ~IPCObject ( ) { ; }
00177                         
00178   protected:
00179     IPCObject ( ) : IPCObjectOperations<T>( TP::threaded() )
00180     { ; }
00181     
00182   private:    
00184     // Disable copying
00186     IPCObject ( const IPCObject & );
00187     IPCObject & operator=( const IPCObject & );
00188 };
00189 
00190 
00198 template <class T>
00199 class IPCObject<T,ipc::single_thread> : public IPCObjectOperations<T>
00200 {  
00201   public:
00202       
00203     virtual ~IPCObject ( ) { ; }
00204                         
00205   protected:
00206   
00209     IPCObject ( )
00210       : IPCObjectOperations<T>( ipc::single_thread::threaded() )
00211     { ; }
00212     
00219     IPCObject ( const IPCObject * object )
00220       : IPCObjectOperations<T>( object )
00221     { ; }
00222     
00223   private:    
00225     // Disable copying
00227     IPCObject ( const IPCObject & );
00228     IPCObject & operator=( const IPCObject & );
00229 };
00230 
00235 template <class T>
00236 class IPCNamedObjectOperations : public IPCObjectBase<T>,
00237                                  public virtual IPCServant
00238 {
00239     const std::string & oid() const { return name_; }
00240     
00241     IPCPartition        partition_;
00242     std::string         name_;
00243 
00244   protected:
00245     IPCNamedObjectOperations (  const IPCPartition & partition,
00246                                 const std::string & name,
00247                                 bool threaded )
00248       : IPCObjectBase<T>( threaded ),
00249         partition_( partition ),
00250         name_( name )
00251     { ; }
00252 
00253     IPCNamedObjectOperations (  const IPCPartition & partition,
00254                                 const std::string & name,
00255                                 const IPCNamedObjectOperations * op )
00256       : IPCObjectBase<T>( op ),
00257         partition_( partition ),
00258         name_( name )
00259     { ; }
00260 
00261   public:
00266     const std::string  & name      ( ) const { return name_; }
00267     
00271     const IPCPartition & partition ( ) const { return partition_; }
00272         
00278     void publish ( ) throw ( daq::ipc::InvalidPartition, daq::ipc::InvalidObjectName ) {
00279         ipc::servant_var ref = _this();
00280         partition().publish( name(), ipc::util::getTypeName( this ), ref );
00281     }
00282     
00289     void withdraw ( ) throw ( daq::ipc::InvalidPartition, daq::ipc::ObjectNotFound, daq::ipc::InvalidObjectName ) {
00290         partition().withdraw( name(), ipc::util::getTypeName( this ) );
00291     }
00292 };
00293 
00317 template <class T, class TP = ipc::multi_thread>
00318 class IPCNamedObject : public IPCNamedObjectOperations<T>
00319 {
00320   public:
00321         
00322     virtual ~IPCNamedObject ( ) { ; }
00323   protected:
00324 
00330     IPCNamedObject (    const std::string & name )
00331       : IPCNamedObjectOperations<T>( IPCPartition(), name, TP::threaded() )
00332     { ; }
00333     
00340     IPCNamedObject (    const IPCPartition & partition, 
00341                         const std::string & name )
00342       : IPCNamedObjectOperations<T>( partition, name, TP::threaded() )
00343     { ; }
00344 
00345   private:
00347     // Disable copying
00349     IPCNamedObject ( const IPCNamedObject & );
00350     IPCNamedObject & operator= ( const IPCNamedObject & );
00351 };
00352 
00360 template <class T>
00361 class IPCNamedObject<T,ipc::single_thread> : public IPCNamedObjectOperations<T>
00362 {
00363   public:
00364         
00365     virtual ~IPCNamedObject ( ) { ; }
00366 
00367   protected:
00368 
00372     IPCNamedObject (    const std::string & name )
00373       : IPCNamedObjectOperations<T>( IPCPartition(), name, ipc::single_thread::threaded() )
00374     { ; }
00375     
00380     IPCNamedObject (    const IPCPartition & partition, 
00381                         const std::string & name )
00382       : IPCNamedObjectOperations<T>( partition, name, ipc::single_thread::threaded() )
00383     { ; }
00384 
00392     IPCNamedObject (    const std::string & name,
00393                         const IPCNamedObject * object )
00394       : IPCNamedObjectOperations<T>( IPCPartition(), name, object )
00395     { ; }
00396     
00404     IPCNamedObject (    const IPCPartition & partition, 
00405                         const std::string & name, 
00406                         const IPCNamedObject * object )
00407       : IPCNamedObjectOperations<T>( partition, name, object )
00408     { ; }
00409     
00410   private:
00412     // Disable copying
00414     IPCNamedObject ( const IPCNamedObject & );
00415     IPCNamedObject & operator= ( const IPCNamedObject & );
00416 };
00417 
00418 #endif // IPC_OBJECT_H

Generated on Tue Aug 8 17:08:21 2006 for IPC User API by  doxygen 1.4.7