From e2f753364e8d1dfe3011ecd7ed9c73a9f1e87e88 Mon Sep 17 00:00:00 2001 From: David Steele Date: Thu, 24 Aug 2023 17:15:32 +0100 Subject: [PATCH] Fixed network client to trigger main thread Main thread Trigger should be created on the event thread, not in client threads. Caused problems with the trigger implementation, as that stored main loop context in thread local storage, so was always 0 / NULL, and this caused the network client to crash or do nothing, depending on the chosen main loop implementation. Change-Id: I483cb1dc55b1ff4f6cf81434780bcd560f2f57a9 Signed-off-by: David Steele --- .../network/common/client-send-data-interface.h | 9 ++++++++- .../network/common/network-performance-client.cpp | 23 +++++++++------------- .../network/common/network-performance-server.cpp | 18 ++++++++++++++++- .../network/common/network-performance-server.h | 15 ++++++++++++-- 4 files changed, 47 insertions(+), 18 deletions(-) diff --git a/dali/internal/network/common/client-send-data-interface.h b/dali/internal/network/common/client-send-data-interface.h index 18a5899..9d46e2b 100644 --- a/dali/internal/network/common/client-send-data-interface.h +++ b/dali/internal/network/common/client-send-data-interface.h @@ -2,7 +2,7 @@ #define DALI_INTERNAL_ADAPTOR_CLIENT_SEND_DATA_INTERFACE_H /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,8 @@ * */ +#include + namespace Dali { namespace Internal @@ -31,6 +33,11 @@ class ClientSendDataInterface { public: /** + * Trigger the main thread automation callback + */ + virtual void TriggerMainThreadAutomation(CallbackBase* callback) = 0; + + /** * @brief Sends data to the client * @param[in] data pointer to some data * @param[in] bufferSizeInBytes how big the buffer is in bytes diff --git a/dali/internal/network/common/network-performance-client.cpp b/dali/internal/network/common/network-performance-client.cpp index b4e0719..b77e4e3 100644 --- a/dali/internal/network/common/network-performance-client.cpp +++ b/dali/internal/network/common/network-performance-client.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -132,12 +132,7 @@ void TriggerOnMainThread(unsigned int clientId, ClientSendDataInterface& sendDat // this needs to be run on the main thread, use the trigger event.... AutomationCallback* callback = new AutomationCallback(clientId, sendDataInterface); lambda(callback); - - // create a trigger event that automatically deletes itself after the callback has run in the main thread - TriggerEventInterface* interface = TriggerEventFactory::CreateTriggerEvent(callback, TriggerEventInterface::DELETE_AFTER_TRIGGER); - - // asynchronous call, the call back will be run sometime later on the main thread - interface->Trigger(); + sendDataInterface.TriggerMainThreadAutomation(callback); } } // unnamed namespace @@ -190,10 +185,10 @@ bool NetworkPerformanceClient::TransmitMarker(const PerformanceMarker& marker, c if(mConsoleClient) { // write out the time stamp - char *buffer; - double usec = marker.GetTimeStamp().microseconds; - int size = asprintf(&buffer, "%.6f (seconds), %s\n", usec * MICROSECONDS_TO_SECOND, description); - auto retVal = mSocket->Write(buffer, size); + char* buffer; + double usec = marker.GetTimeStamp().microseconds; + int size = asprintf(&buffer, "%.6f (seconds), %s\n", usec * MICROSECONDS_TO_SECOND, description); + auto retVal = mSocket->Write(buffer, size); free(buffer); return retVal; } @@ -249,20 +244,20 @@ void NetworkPerformanceClient::ProcessCommand(char* buffer, unsigned int bufferS case PerformanceProtocol::DUMP_SCENE_GRAPH: { - TriggerOnMainThread(mClientId, mSendDataInterface, [&](AutomationCallback* callback){callback->AssignDumpSceneCommand();}); + TriggerOnMainThread(mClientId, mSendDataInterface, [&](AutomationCallback* callback) { callback->AssignDumpSceneCommand(); }); break; } case PerformanceProtocol::SET_PROPERTIES: { - TriggerOnMainThread(mClientId, mSendDataInterface, [&](AutomationCallback* callback){callback->AssignSetPropertyCommand(stringParam);}); + TriggerOnMainThread(mClientId, mSendDataInterface, [&](AutomationCallback* callback) { callback->AssignSetPropertyCommand(stringParam); }); response = "Completed"; break; } case PerformanceProtocol::CUSTOM_COMMAND: { - TriggerOnMainThread(mClientId, mSendDataInterface, [&](AutomationCallback* callback){callback->AssignCustomCommand(std::move(stringParam));}); + TriggerOnMainThread(mClientId, mSendDataInterface, [&](AutomationCallback* callback) { callback->AssignCustomCommand(std::move(stringParam)); }); response = "Completed"; break; } diff --git a/dali/internal/network/common/network-performance-server.cpp b/dali/internal/network/common/network-performance-server.cpp index 44e5460..7b155ca 100644 --- a/dali/internal/network/common/network-performance-server.cpp +++ b/dali/internal/network/common/network-performance-server.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,6 +48,7 @@ struct ClientThreadInfo NetworkPerformanceServer::NetworkPerformanceServer(AdaptorInternalServices& adaptorServices, const EnvironmentOptions& logOptions) : mSocketFactory(adaptorServices.GetSocketFactoryInterface()), + mTrigger(new EventThreadCallback(MakeCallback(this, &NetworkPerformanceServer::AutomationCallback))), mLogOptions(logOptions), mServerThread(0), mListeningSocket(NULL), @@ -304,6 +305,21 @@ void NetworkPerformanceServer::TransmitMarker(const PerformanceMarker& marker, c } } +void NetworkPerformanceServer::TriggerMainThreadAutomation(CallbackBase* callback) +{ + // Called from client thread. + mClientCallback = callback; + mTrigger->Trigger(); +} + +void NetworkPerformanceServer::AutomationCallback() +{ + if(mClientCallback) + { + Dali::CallbackBase::Execute(*mClientCallback); + } +} + void NetworkPerformanceServer::StopClients() { // prevent clients been added / deleted while stopping all clients diff --git a/dali/internal/network/common/network-performance-server.h b/dali/internal/network/common/network-performance-server.h index 2896f90..82bf601 100644 --- a/dali/internal/network/common/network-performance-server.h +++ b/dali/internal/network/common/network-performance-server.h @@ -2,7 +2,7 @@ #define DALI_INTERNAL_ADAPTOR_NETWORK_PERFORMANCE_SERVER_H /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ #include // INTERNAL INCLUDES +#include #include #include #include @@ -98,10 +99,17 @@ public: protected: // ClientSendDataInterface /** + * @copydoc ClientSendDataInterface::TriggerMainThreadAutomation() + */ + void TriggerMainThreadAutomation(CallbackBase* callback) override; + + /** * @copydoc ClientSendDataInterface::ClientSendDataInterface() */ void SendData(const char* const data, unsigned int bufferSizeInBytes, unsigned int clientId) override; + void AutomationCallback(); + private: /** * Helper for the thread calling the entry function. @@ -152,7 +160,10 @@ private: NetworkPerformanceServer(const NetworkPerformanceServer&); ///< undefined copy constructor NetworkPerformanceServer& operator=(const NetworkPerformanceServer&); ///< undefined assignment operator - SocketFactoryInterface& mSocketFactory; ///< used to create sockets + SocketFactoryInterface& mSocketFactory; ///< used to create sockets + std::unique_ptr mTrigger; ///< For waking up main thread + CallbackBase* mClientCallback; ///< Wrong thread callback! + const EnvironmentOptions& mLogOptions; ///< log options Dali::Vector mClients; ///< list of connected clients pthread_t mServerThread; ///< thread that listens for new connections -- 2.7.4