00001 /* 00002 * 00003 * 00004 * Distributed under the OpenDDS License. 00005 * See: http://www.opendds.org/license.html 00006 */ 00007 00008 #ifndef OPENDDS_DCPS_THREADSYNCH_H 00009 #define OPENDDS_DCPS_THREADSYNCH_H 00010 00011 #include "dds/DCPS/dcps_export.h" 00012 #include "ThreadSynchWorker.h" 00013 #include "dds/DCPS/PoolAllocationBase.h" 00014 00015 namespace OpenDDS { 00016 namespace DCPS { 00017 00018 class ThreadSynchResource; 00019 00020 /** 00021 * This class is the base class for different ThreadSynch stratege, currently 00022 * only the thread per connection strategy is implemented and used. 00023 * 00024 * Notes for object ownership: 00025 * 1) Pointer to TransportSendStrategy object (as ThreadSynchWorker) directly but not 00026 * reference counted. It won't have access problem during it lifetime because the 00027 * TransportSendStrategy object owns this ThreadSynch object. 00028 * 2) The ThreadSynch object is created by the ThreadSynchResource object and it owns 00029 * the ThreadSynchResource object. 00030 */ 00031 class OpenDDS_Dcps_Export ThreadSynch : public PoolAllocationBase { 00032 public: 00033 00034 virtual ~ThreadSynch(); 00035 00036 /// The worker must introduce himself to this ThreadSynch object. 00037 /// It is the worker object that "owns" this ThreadSynch object. 00038 /// Returns 0 for success, -1 for failure. 00039 int register_worker(ThreadSynchWorker* worker); 00040 00041 /// Our owner, the worker_, is breaking our relationship. 00042 void unregister_worker(); 00043 00044 /// The ThreadSynchWorker would like to have its perform_work() called 00045 /// from the appropriate thread once the ThreadSynchResource claims 00046 /// that it is_ready_for_work(). 00047 virtual void work_available() = 0; 00048 00049 protected: 00050 00051 // This ThreadSynch object takes ownership of the resource. 00052 ThreadSynch(ThreadSynchResource* resource); 00053 00054 /// This will tell the worker_ to perform_work(). 00055 /// A return value of 0 means that the perform_work() did all the 00056 /// work necessary, and we shouldn't ask it to perform_work() again, 00057 /// unless we receive another work_available() call. It won't hurt 00058 /// if we call perform_work() and it has nothing to do - it will 00059 /// immediately return 0 to indicate it has nothing more to do (at 00060 /// the moment). 00061 /// A return value of 1 means that the perform_work() completed, and 00062 /// there is still more work it could do. The perform_work() should 00063 /// be called again in this case. 00064 ThreadSynchWorker::WorkOutcome perform_work(); 00065 00066 int wait_on_clogged_resource(); 00067 00068 /// The default implementation is to do nothing here. The 00069 /// subclass may override the implementation in order to do 00070 /// something when the worker registers. 00071 /// Returns 0 for success, -1 for failure. 00072 virtual int register_worker_i(); 00073 00074 /// The default implementation is to do nothing here. The 00075 /// subclass may override the implementation in order to do 00076 /// something when the worker unregisters. 00077 virtual void unregister_worker_i(); 00078 00079 /// Access the worker implementation directly. 00080 ThreadSynchWorker* worker(); 00081 00082 private: 00083 00084 ThreadSynchWorker* worker_; 00085 ThreadSynchResource* resource_; 00086 }; 00087 00088 } // namespace DCPS 00089 } // namespace OpenDDS 00090 00091 #if defined (__ACE_INLINE__) 00092 #include "ThreadSynch.inl" 00093 #endif /* __ACE_INLINE__ */ 00094 00095 #endif /* OPENDDS_DCPS_THREADSYNCH_H */