8080//
8181// Another challenge when injecting IPC into the ARA communication is that for each
8282// message that comes in, an appropriate thread has to be selected to process it.
83- // For the main thread channel, this is trivial.
83+ // When a new transaction is initiated, the implementation checks whether this is happening
84+ // on the main thread or on any other thread, and chooses the appropriate channel accordingly.
85+ // On the receiving side, calls coming in on the main thread channel are forwarded to the main
86+ // thread (unless the receive code already runs there), and for the other threads the code is
87+ // executed directly on the receive thread.
8488//
85- // For the channel that handles all communication on other threads, the implementation
86- // adds a token to each call message that identifies the sending thread. The reply message
87- // or any stacked call the receiver might make in response to the message will pass back
88- // this thread token, enabling proper routing back to the original sending thread .
89+ // Replies or callbacks are routed back to the originating thread in the sender. This is done
90+ // by adding a token when sending a message that identifies the sending thread, and replies and
91+ // callbacks pass this token back to allow for proper dispatching from the receive thread to the
92+ // thread that initiated the transaction .
8993// Since the actual ARA code is agnostic to IPC being used, the receiving side uses
9094// thread local storage to make the sender's thread token available for all stacked calls
9195// that the ARA code might make in response to the message.
9296//
93- // If a message is received that does not contain the token, this message indicates
94- // the start of a transaction that was initiated on the other side. For this new
95- // transaction, a proper thread has to be selected. This is done based on the message ID -
96- // the current implementation dispatches audio reading to a dedicated dispatch queue and
97- // handles the remaining calls directly on the IPC receive thread.
98- //
9997// Note that there is a crucial difference between the dispatch of a new transaction and
10098// the dispatch of any follow-up messages in the transaction: the initial message is dispatched
10199// to a thread that is potentially executing other code as well in some form of run loop,
@@ -298,15 +296,16 @@ void MessageDispatcher::routeReceivedMessage (MessageID messageID, const Message
298296 else
299297 {
300298 ARA_INTERNAL_ASSERT (messageID != 0 );
301- if (const auto dispatchTarget { _connection->getMessageHandler ()->getDispatchTargetForIncomingTransaction (messageID) })
299+ if (!_sendLock &&
300+ !_connection->wasCreatedOnCurrentThread ())
302301 {
303302 ARA_IPC_LOG (" dispatches received message with ID %i (new transaction)" , messageID);
304303#if defined (_WIN32)
305304 auto params { new APCProcessReceivedMessageParams { this , messageID, decoder } };
306- const auto result { ::QueueUserAPC (APCRouteNewTransactionFunc, dispatchTarget , reinterpret_cast <ULONG_PTR> (params)) };
305+ const auto result { ::QueueUserAPC (APCRouteNewTransactionFunc, _connection-> getCreationThreadDispatchTarget () , reinterpret_cast <ULONG_PTR> (params)) };
307306 ARA_INTERNAL_ASSERT (result != 0 );
308307#elif defined (__APPLE__)
309- dispatch_async (dispatchTarget ,
308+ dispatch_async (_connection-> getCreationThreadDispatchTarget () ,
310309 ^{
311310 _handleReceivedMessage (messageID, decoder);
312311 });
@@ -381,7 +380,7 @@ HANDLE _GetRealCurrentThread ()
381380#endif
382381
383382
384- MessageHandler::MessageHandler ()
383+ Connection::Connection ()
385384: _creationThreadID { std::this_thread::get_id () },
386385#if defined (_WIN32)
387386 _creationThreadDispatchTarget { _GetRealCurrentThread () }
@@ -399,16 +398,6 @@ MessageHandler::MessageHandler ()
399398#endif
400399}
401400
402- MessageHandler::DispatchTarget MessageHandler::getDispatchTargetForIncomingTransaction (MessageID /* messageID*/ )
403- {
404- return (std::this_thread::get_id () == _creationThreadID) ? nullptr : _creationThreadDispatchTarget;
405- }
406-
407-
408- Connection::Connection ()
409- : _creationThreadID { std::this_thread::get_id () }
410- {}
411-
412401Connection::~Connection ()
413402{
414403 delete _otherDispatcher;
@@ -436,7 +425,7 @@ void Connection::setMessageHandler (MessageHandler* messageHandler)
436425void Connection::sendMessage (MessageID messageID, MessageEncoder* encoder, ReplyHandler replyHandler, void * replyHandlerUserData)
437426{
438427 ARA_INTERNAL_ASSERT ((_mainDispatcher != nullptr ) && (_otherDispatcher != nullptr ) && (_messageHandler != nullptr ));
439- if (std::this_thread::get_id () == _creationThreadID )
428+ if (wasCreatedOnCurrentThread ())
440429 _mainDispatcher->sendMessage (messageID, encoder, replyHandler, replyHandlerUserData);
441430 else
442431 _otherDispatcher->sendMessage (messageID, encoder, replyHandler, replyHandlerUserData);
0 commit comments