@@ -93,8 +93,12 @@ void TrHiveDaemon::shutdown()
9393bool TrHiveDaemon::createClient (TrDocumentRequestInit &requestInit, function<void (pid_t )> callback)
9494{
9595 if (commandSender == nullptr )
96+ {
97+ DEBUG (LOG_TAG_ERROR, " Skipped creating a client because the command sender is not initialized." );
9698 return false ;
99+ }
97100
101+ unique_lock<shared_mutex> lock (mutexForCommand);
98102 hive_comm::TrCreateClientRequest req (requestInit);
99103 {
100104 unique_lock<shared_mutex> lock (mutexForCreateProcessCallbacks);
@@ -106,7 +110,7 @@ bool TrHiveDaemon::createClient(TrDocumentRequestInit &requestInit, function<voi
106110bool TrHiveDaemon::terminateClient (uint32_t id)
107111{
108112 assert (commandSender != nullptr );
109-
113+ unique_lock<shared_mutex> lock (mutexForCommand);
110114 hive_comm::TrTerminateClientRequest req (id);
111115 return commandSender->sendCommand (req);
112116}
@@ -115,7 +119,12 @@ void TrHiveDaemon::tick()
115119{
116120 recvOutput ();
117121 if (!checkDaemonAlive ())
122+ {
123+ DEBUG (LOG_TAG_ERROR, " The hive daemon is not alive, cleaning up and restarting..." );
124+ cleanupDaemonResources ();
125+ start ();
118126 return ;
127+ }
119128
120129 // Check for new client
121130 acceptChanClient (0 );
@@ -188,13 +197,17 @@ void TrHiveDaemon::onDeamonProcess()
188197
189198void TrHiveDaemon::onNewChanClient (TrOneShotClient<hive_comm::TrHiveCommandMessage> &client)
190199{
191- if (commandReceiver != nullptr || commandSender ! = nullptr )
200+ if (commandReceiver == nullptr && commandSender = = nullptr )
192201 {
193- commandReceiver.reset ();
194- commandSender.reset ();
202+ commandReceiver = make_unique<hive_comm::TrHiveCommandReceiver>(&client);
203+ commandSender = make_unique<hive_comm::TrHiveCommandSender>(&client);
204+ }
205+ else
206+ {
207+ commandChanServer->removeClient (&client);
208+ DEBUG (LOG_TAG_ERROR,
209+ " Received a new hived command channel client, but the command receiver or sender is already initialized." );
195210 }
196- commandReceiver = make_unique<hive_comm::TrHiveCommandReceiver>(&client);
197- commandSender = make_unique<hive_comm::TrHiveCommandSender>(&client);
198211}
199212
200213void TrHiveDaemon::acceptChanClient (int timeout)
@@ -238,6 +251,45 @@ bool TrHiveDaemon::checkDaemonAlive()
238251 return true ;
239252}
240253
254+ void TrHiveDaemon::cleanupDaemonResources ()
255+ {
256+ // Reset daemon state
257+ daemonPid = -1 ;
258+ daemonReady = false ;
259+
260+ // Close child pipes if they're open
261+ if (childPipes[0 ] != -1 )
262+ {
263+ close (childPipes[0 ]);
264+ childPipes[0 ] = -1 ;
265+ }
266+ if (childPipes[1 ] != -1 )
267+ {
268+ close (childPipes[1 ]);
269+ childPipes[1 ] = -1 ;
270+ }
271+
272+ // Stop and reset command receiver worker
273+ if (recvWorker != nullptr )
274+ {
275+ recvWorker->stop ();
276+ recvWorker.reset ();
277+ }
278+
279+ // Reset command channel components
280+ if (commandReceiver != nullptr )
281+ commandReceiver.reset ();
282+ if (commandSender != nullptr )
283+ commandSender.reset ();
284+ if (commandChanServer != nullptr )
285+ commandChanServer.reset ();
286+
287+ // Clear pending callbacks and notify them of failure
288+ pendingCreateProcessCallbacks.clear ();
289+
290+ DEBUG (LOG_TAG_CONTENT, " Hive daemon resources cleaned up." );
291+ }
292+
241293bool TrHiveDaemon::recvOutput ()
242294{
243295 if (!started ())
@@ -300,22 +352,29 @@ void TrHiveDaemon::recvCommand()
300352 case hive_comm::TrHiveCommandType::CreateClientResponse:
301353 {
302354 auto res = hive_comm::TrHiveCommandBase::FromMessage<hive_comm::TrCreateClientResponse>(commandMessage);
355+ DEBUG (LOG_TAG_CONTENT, " << CreateClientResponse(%d) with pid(%d)" , res.documentId , res.pid );
356+
303357 function<void (pid_t )> callback;
304358 {
305359 shared_lock<shared_mutex> lock (mutexForCreateProcessCallbacks);
306360 auto it = pendingCreateProcessCallbacks.find (res.documentId );
307361 if (it != pendingCreateProcessCallbacks.end ())
308362 {
309363 callback = it->second ;
364+ pendingCreateProcessCallbacks.erase (it);
310365 }
311366 }
312- if (callback)
367+
368+ if (TR_LIKELY (callback))
313369 callback (res.pid );
370+ else
371+ DEBUG (LOG_TAG_ERROR, " No callback found for CreateClientResponse(%d)" , res.documentId );
314372 break ;
315373 }
316374 case hive_comm::TrHiveCommandType::TerminateClientResponse:
317375 {
318376 auto res = hive_comm::TrHiveCommandBase::FromMessage<hive_comm::TrTerminateClientResponse>(commandMessage);
377+ DEBUG (LOG_TAG_CONTENT, " << TerminateClientResponse(%d)" , res.documentId );
319378 // TODO: handle the response?
320379 break ;
321380 }
@@ -327,7 +386,8 @@ void TrHiveDaemon::recvCommand()
327386 case hive_comm::TrHiveCommandType::OnExitEvent:
328387 {
329388 auto exitEvent = hive_comm::TrHiveCommandBase::FromMessage<hive_comm::TrOnExitEvent>(commandMessage);
330- DEBUG (LOG_TAG_ERROR, " Received exit event from client(%d): %d" , exitEvent.documentId , exitEvent.code );
389+ DEBUG (LOG_TAG_CONTENT, " << OnExitEvent(%d) with code(%d)" , exitEvent.documentId , exitEvent.code );
390+
331391 auto contentToExit = constellation->contentManager ->getContent (exitEvent.documentId , true );
332392 if (contentToExit != nullptr )
333393 contentToExit->onClientProcessExited (exitEvent.code );
0 commit comments