Fixed network client to trigger main thread 92/297992/1
authorDavid Steele <david.steele@samsung.com>
Thu, 24 Aug 2023 16:15:32 +0000 (17:15 +0100)
committerDavid Steele <david.steele@samsung.com>
Tue, 29 Aug 2023 15:22:08 +0000 (16:22 +0100)
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 <david.steele@samsung.com>
dali/internal/network/common/client-send-data-interface.h
dali/internal/network/common/network-performance-client.cpp
dali/internal/network/common/network-performance-server.cpp
dali/internal/network/common/network-performance-server.h

index 18a5899..9d46e2b 100644 (file)
@@ -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 <dali/public-api/signals/callback.h>
+
 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
index b4e0719..b77e4e3 100644 (file)
@@ -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;
     }
index 44e5460..7b155ca 100644 (file)
@@ -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
index 2896f90..82bf601 100644 (file)
@@ -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 <pthread.h>
 
 // INTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/event-thread-callback.h>
 #include <dali/internal/adaptor/common/adaptor-internal-services.h>
 #include <dali/internal/network/common/network-performance-client.h>
 #include <dali/internal/system/common/environment-options.h>
@@ -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<EventThreadCallback> mTrigger;        ///< For waking up main thread
+  CallbackBase*                        mClientCallback; ///< Wrong thread callback!
+
   const EnvironmentOptions&               mLogOptions;           ///< log options
   Dali::Vector<NetworkPerformanceClient*> mClients;              ///< list of connected clients
   pthread_t                               mServerThread;         ///< thread that listens for new connections