@@ -111,7 +111,7 @@ void DataPublisher::AcceptConnection(const SubscriberConnectionPtr& connection,
111111
112112 if (connectionAccepted)
113113 {
114- DispatchClientConnected (connection. get ( ));
114+ DispatchClientConnected (AddDispatchReference (connection ));
115115 }
116116 else
117117 {
@@ -132,7 +132,7 @@ void DataPublisher::AcceptConnection(const SubscriberConnectionPtr& connection,
132132
133133void DataPublisher::ConnectionTerminated (const SubscriberConnectionPtr& connection)
134134{
135- DispatchClientDisconnected (connection. get ( ));
135+ DispatchClientDisconnected (AddDispatchReference (connection ));
136136}
137137
138138void DataPublisher::RemoveConnection (const SubscriberConnectionPtr& connection)
@@ -144,6 +144,26 @@ void DataPublisher::RemoveConnection(const SubscriberConnectionPtr& connection)
144144 m_subscriberConnections.erase (connection);
145145}
146146
147+ SubscriberConnection* DataPublisher::AddDispatchReference (SubscriberConnectionPtr connectionRef)
148+ {
149+ SubscriberConnection* connectionPtr = connectionRef.get ();
150+
151+ // Hold onto subscriber connection shared pointer until it's delivered
152+ m_subscriberConnectionDispatchRefs.emplace (connectionRef);
153+
154+ return connectionPtr;
155+ }
156+
157+ SubscriberConnectionPtr DataPublisher::ReleaseDispatchReference (SubscriberConnection* connectionPtr)
158+ {
159+ const SubscriberConnectionPtr connectionRef = connectionPtr->GetReference ();
160+
161+ // Remove used reference to subscriber connection pointer
162+ m_subscriberConnectionDispatchRefs.erase (connectionRef);
163+
164+ return connectionRef;
165+ }
166+
147167void DataPublisher::Dispatch (const DispatcherFunction& function)
148168{
149169 Dispatch (function, nullptr , 0 , 0 );
@@ -252,7 +272,7 @@ void DataPublisher::ClientConnectedDispatcher(DataPublisher* source, const vecto
252272 const SubscriberConnectionCallback clientConnectedCallback = source->m_clientConnectedCallback ;
253273
254274 if (clientConnectedCallback != nullptr )
255- clientConnectedCallback (source, connection-> GetReference ( ));
275+ clientConnectedCallback (source, source-> ReleaseDispatchReference (connection ));
256276 }
257277}
258278
@@ -263,11 +283,12 @@ void DataPublisher::ClientDisconnectedDispatcher(DataPublisher* source, const st
263283 if (source != nullptr )
264284 {
265285 const SubscriberConnectionCallback clientDisconnectedCallback = source->m_clientDisconnectedCallback ;
286+ const SubscriberConnectionPtr subscriberConnectionRef = source->ReleaseDispatchReference (connection);
266287
267288 if (clientDisconnectedCallback != nullptr )
268- clientDisconnectedCallback (source, connection-> GetReference () );
289+ clientDisconnectedCallback (source, subscriberConnectionRef );
269290
270- source->RemoveConnection (connection-> GetReference () );
291+ source->RemoveConnection (subscriberConnectionRef );
271292 }
272293}
273294
@@ -280,7 +301,7 @@ void DataPublisher::ProcessingIntervalChangeRequestedDispatcher(DataPublisher* s
280301 const SubscriberConnectionCallback temporalProcessingIntervalChangeRequestedCallback = source->m_processingIntervalChangeRequestedCallback ;
281302
282303 if (temporalProcessingIntervalChangeRequestedCallback != nullptr )
283- temporalProcessingIntervalChangeRequestedCallback (source, connection-> GetReference ( ));
304+ temporalProcessingIntervalChangeRequestedCallback (source, source-> ReleaseDispatchReference (connection ));
284305 }
285306}
286307
@@ -293,7 +314,7 @@ void DataPublisher::TemporalSubscriptionRequestedDispatcher(DataPublisher* sourc
293314 const SubscriberConnectionCallback temporalSubscriptionRequestedCallback = source->m_temporalSubscriptionRequestedCallback ;
294315
295316 if (temporalSubscriptionRequestedCallback != nullptr )
296- temporalSubscriptionRequestedCallback (source, connection-> GetReference ( ));
317+ temporalSubscriptionRequestedCallback (source, source-> ReleaseDispatchReference (connection ));
297318 }
298319}
299320
@@ -306,7 +327,7 @@ void DataPublisher::TemporalSubscriptionCanceledDispatcher(DataPublisher* source
306327 const SubscriberConnectionCallback temporalSubscriptionCanceledCallback = source->m_temporalSubscriptionCanceledCallback ;
307328
308329 if (temporalSubscriptionCanceledCallback != nullptr )
309- temporalSubscriptionCanceledCallback (source, connection-> GetReference ( ));
330+ temporalSubscriptionCanceledCallback (source, source-> ReleaseDispatchReference (connection ));
310331 }
311332}
312333
@@ -319,7 +340,7 @@ void DataPublisher::UserCommandDispatcher(DataPublisher* source, const std::vect
319340 const UserCommandCallback userCommandCallback = source->m_userCommandCallback ;
320341
321342 if (userCommandCallback != nullptr )
322- userCommandCallback (source, userCommandData-> connection -> GetReference ( ), userCommandData->command , userCommandData->data );
343+ userCommandCallback (source, source-> ReleaseDispatchReference (userCommandData-> connection ), userCommandData->command , userCommandData->data );
323344 }
324345
325346 delete userCommandData;
@@ -782,6 +803,9 @@ void DataPublisher::Start(const TcpEndPoint& endpoint)
782803 if (m_started)
783804 Stop ();
784805
806+ // Let any pending start operation complete before stop - prevents destruction stop before start is completed
807+ ScopeLock lock (m_connectActionMutex);
808+
785809#if BOOST_LEGACY
786810 m_commandChannelService.reset ();
787811#else
@@ -827,6 +851,9 @@ void DataPublisher::Start(const string& networkInterfaceIP, uint16_t port)
827851
828852void DataPublisher::Stop ()
829853{
854+ // Let any pending start operation complete before stop - prevents destruction stop before start is completed
855+ ScopeLock lock (m_connectActionMutex);
856+
830857 // Notify running threads that the
831858 // publisher is shutting down
832859 m_shuttingDown = true ;
0 commit comments