00001 /* 00002 * 00003 * 00004 * Distributed under the OpenDDS License. 00005 * See: http://www.opendds.org/license.html 00006 */ 00007 00008 #ifndef OPENDDS_DCPS_INSTANCESTATE_H 00009 #define OPENDDS_DCPS_INSTANCESTATE_H 00010 00011 #include "dcps_export.h" 00012 #include "ace/Time_Value.h" 00013 #include "dds/DdsDcpsInfrastructureC.h" 00014 #include "dds/DCPS/Definitions.h" 00015 #include "dds/DCPS/GuidUtils.h" 00016 #include "dds/DCPS/PoolAllocator.h" 00017 #include "dds/DCPS/RepoIdTypes.h" 00018 00019 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00020 #pragma once 00021 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00022 00023 OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL 00024 00025 namespace OpenDDS { 00026 namespace DCPS { 00027 00028 class DataReaderImpl; 00029 class ReceivedDataElement; 00030 00031 /** 00032 * @class InstanceState 00033 * 00034 * @brief manage the states of a received data instance. 00035 * 00036 * Provide a mechanism to manage the view state and instance 00037 * state values for an instance contained within a DataReader. 00038 * The instance_state and view_state are managed by this class. 00039 * Accessors are provided to query the current value of each of 00040 * these states. 00041 */ 00042 class OpenDDS_Dcps_Export InstanceState : public ACE_Event_Handler { 00043 public: 00044 InstanceState(DataReaderImpl* reader, 00045 ACE_Recursive_Thread_Mutex& lock, 00046 DDS::InstanceHandle_t handle); 00047 00048 virtual ~InstanceState(); 00049 00050 /// Populate the SampleInfo structure 00051 void sample_info(DDS::SampleInfo& si, 00052 const ReceivedDataElement* de); 00053 00054 /// Access instance state. 00055 DDS::InstanceStateKind instance_state() const; 00056 00057 /// Access view state. 00058 DDS::ViewStateKind view_state() const; 00059 00060 /// Access disposed generation count 00061 size_t disposed_generation_count() const; 00062 00063 /// Access no writers generation count 00064 size_t no_writers_generation_count() const; 00065 00066 /// DISPOSE message received for this instance. 00067 /// Return flag indicates whether the instance state was changed. 00068 /// This flag is used by concrete DataReader to determine whether 00069 /// it should notify listener. If state is not changed, the dispose 00070 /// message is ignored. 00071 bool dispose_was_received(const PublicationId& writer_id); 00072 00073 /// UNREGISTER message received for this instance. 00074 /// Return flag indicates whether the instance state was changed. 00075 /// This flag is used by concrete DataReader to determine whether 00076 /// it should notify listener. If state is not changed, the unregister 00077 /// message is ignored. 00078 bool unregister_was_received(const PublicationId& writer_id); 00079 00080 /// Data sample received for this instance. 00081 void data_was_received(const PublicationId& writer_id); 00082 00083 /// LIVELINESS message received for this DataWriter. 00084 void lively(const PublicationId& writer_id); 00085 00086 /// A read or take operation has been performed on this instance. 00087 void accessed(); 00088 00089 bool most_recent_generation(ReceivedDataElement* item) const; 00090 00091 /// DataReader has become empty. Returns true if the instance was released. 00092 bool empty(bool value); 00093 00094 /// Schedule a pending release of resources. 00095 void schedule_pending(); 00096 00097 /// Schedule an immediate release of resources. 00098 void schedule_release(); 00099 00100 /// Cancel a scheduled or pending release of resources. 00101 void cancel_release(); 00102 00103 /// Remove the instance if it's instance has no samples 00104 /// and no writers. 00105 /// Returns true if the instance was released. 00106 bool release_if_empty(); 00107 00108 /// Remove the instance immediately. 00109 void release(); 00110 00111 /// tell this instance when a DataWriter transitions to NOT_ALIVE 00112 void writer_became_dead(const PublicationId& writer_id, 00113 int num_alive_writers, 00114 const ACE_Time_Value& when); 00115 00116 DataReaderImpl* data_reader() const; 00117 00118 virtual int handle_timeout(const ACE_Time_Value& current_time, 00119 const void* arg); 00120 00121 void set_owner (const PublicationId& owner); 00122 PublicationId& get_owner (); 00123 bool is_exclusive () const; 00124 bool registered(); 00125 void registered (bool flag); 00126 bool is_last (const PublicationId& pub); 00127 00128 bool no_writer () const; 00129 00130 void reset_ownership (DDS::InstanceHandle_t instance); 00131 00132 DDS::InstanceHandle_t instance_handle() const { return handle_; } 00133 00134 /// Return string of the name of the current instance state 00135 OPENDDS_STRING instance_state_string() const 00136 { 00137 return instance_state_string(instance_state_); 00138 } 00139 00140 /// Return string of the name of the instance state kind or mask passed 00141 static OPENDDS_STRING instance_state_string(DDS::InstanceStateKind value); 00142 00143 private: 00144 ACE_Recursive_Thread_Mutex& lock_; 00145 00146 /** 00147 * Current instance state. 00148 * 00149 * Can have values defined as: 00150 * 00151 * DDS::ALIVE_INSTANCE_STATE 00152 * DDS::NOT_ALIVE_DISPOSED_INSTANCE_STATE 00153 * DDS::NOT_ALIVE_NO_WRITERS_INSTANCE_STATE 00154 * 00155 * and can be checked with the masks: 00156 * 00157 * DDS::ANY_INSTANCE_STATE 00158 * DDS::NOT_ALIVE_INSTANCE_STATE 00159 */ 00160 DDS::InstanceStateKind instance_state_; 00161 00162 /** 00163 * Current instance view state. 00164 * 00165 * Can have values defined as: 00166 * 00167 * DDS::NEW_VIEW_STATE 00168 * DDS::NOT_NEW_VIEW_STATE 00169 * 00170 * and can be checked with the mask: 00171 * 00172 * DDS::ANY_VIEW_STATE 00173 */ 00174 DDS::ViewStateKind view_state_; 00175 00176 /// Number of times the instance state changes 00177 /// from NOT_ALIVE_DISPOSED to ALIVE. 00178 size_t disposed_generation_count_; 00179 00180 /// Number of times the instance state changes 00181 /// from NOT_ALIVE_NO_WRITERS to ALIVE. 00182 size_t no_writers_generation_count_; 00183 00184 /** 00185 * Keep track of whether the DataReader is empty or not. 00186 */ 00187 bool empty_; 00188 00189 /** 00190 * Keep track of whether the instance is waiting to be released. 00191 */ 00192 bool release_pending_; 00193 00194 /** 00195 * Keep track of a scheduled release timer. 00196 */ 00197 long release_timer_id_; 00198 00199 /** 00200 * Reference to our containing reader. This is used to call back 00201 * and notify the reader that liveliness has been lost on this 00202 * instance. It is also queried to determine if the DataReader is 00203 * empty -- that it contains no more sample data. 00204 */ 00205 DataReaderImpl* reader_; 00206 DDS::InstanceHandle_t handle_; 00207 00208 RepoIdSet writers_; 00209 PublicationId owner_; 00210 bool exclusive_; 00211 /// registered with participant so it can be called back as 00212 /// the owner is updated. 00213 bool registered_; 00214 }; 00215 00216 } // namespace DCPS 00217 } // namespace OpenDDS 00218 00219 OPENDDS_END_VERSIONED_NAMESPACE_DECL 00220 00221 #if defined (__ACE_INLINE__) 00222 # include "InstanceState.inl" 00223 #endif /* __ACE_INLINE__ */ 00224 00225 #endif /* OPENDDS_DCPS_INSTANCESTATE_H */