StoreCommand fixed and avoid Spurious Wakeups. 38/16938/5
Cedric Delamarre [Thu, 30 Jul 2015 11:47:05 +0000 (13:47 +0200)]
start Scilab with gui and click on cross to close it.
process never exit.

Change-Id: I960414ba2203c21dadee7d3452fb7f8c1f73f03d

scilab/modules/ast/includes/system_env/threadmanagement.hxx
scilab/modules/ast/src/cpp/system_env/configvariable.cpp
scilab/modules/ast/src/cpp/system_env/threadmanagement.cpp
scilab/modules/core/src/cpp/storeCommand.cpp

index 435b275..5ada1b6 100644 (file)
@@ -43,9 +43,14 @@ private :
     static __threadSignal m_CommandStored;
     static __threadSignalLock m_CommandStoredLock;
 
+    // used to avoid "Spurious Wakeups"
+    static bool m_AstPendingWasSignalled;
+    static bool m_ConsoleExecDoneWasSignalled;
+    static bool m_AwakeRunnerWasSignalled;
+    static bool m_StartPendingWasSignalled;
+    static bool m_CommandStoredWasSignalled;
 
 public :
-
     static void initialize(void);
 
     static void LockStart(void);
index 10c28b7..b9ef60d 100644 (file)
@@ -115,11 +115,6 @@ bool ConfigVariable::m_bForceQuit = false;
 void ConfigVariable::setForceQuit(bool _bForceQuit)
 {
     m_bForceQuit = _bForceQuit;
-    // unlock scilabReadAndExecCommand thread which wait for a command.
-    if (m_bForceQuit)
-    {
-        ThreadManagement::SendCommandStoredSignal();
-    }
 }
 
 bool ConfigVariable::getForceQuit(void)
index ec71c37..5e48603 100644 (file)
 
 #include "threadmanagement.hxx"
 
+//#define DEBUG_THREAD
+#ifdef DEBUG_THREAD
+#include <iostream>
+#endif // DEBUG_THREAD
+
 __threadLock ThreadManagement::m_StartLock;
 __threadLock ThreadManagement::m_RunnerLock;
 __threadLock ThreadManagement::m_ParseLock;
@@ -32,6 +37,11 @@ __threadSignalLock ThreadManagement::m_StartPendingLock;
 __threadSignal ThreadManagement::m_CommandStored;
 __threadSignalLock ThreadManagement::m_CommandStoredLock;
 
+bool ThreadManagement::m_AstPendingWasSignalled         = false;
+bool ThreadManagement::m_ConsoleExecDoneWasSignalled    = false;
+bool ThreadManagement::m_AwakeRunnerWasSignalled        = false;
+bool ThreadManagement::m_StartPendingWasSignalled       = false;
+bool ThreadManagement::m_CommandStoredWasSignalled      = false;
 
 void ThreadManagement::initialize()
 {
@@ -54,117 +64,196 @@ void ThreadManagement::initialize()
 
     __InitSignal(&m_CommandStored);
     __InitSignalLock(&m_CommandStoredLock);
-
 }
 
 void ThreadManagement::LockStart(void)
 {
+#ifdef DEBUG_THREAD
+    std::cout << "[" << __GetCurrentThreadKey() << "] " << "LockStart" << std::endl;
+#endif // DEBUG_THREAD
     __Lock(&m_StartLock);
 }
 
 void ThreadManagement::UnlockStart(void)
 {
+#ifdef DEBUG_THREAD
+    std::cout << "[" << __GetCurrentThreadKey() << "] " << "UnlockStart" << std::endl;
+#endif // DEBUG_THREAD
     __UnLock(&m_StartLock);
 }
 
 void ThreadManagement::LockParser(void)
 {
+#ifdef DEBUG_THREAD
+    std::cout << "[" << __GetCurrentThreadKey() << "] " << "LockParser" << std::endl;
+#endif // DEBUG_THREAD
     __Lock(&m_ParseLock);
 }
 
 void ThreadManagement::UnlockParser(void)
 {
+#ifdef DEBUG_THREAD
+    std::cout << "[" << __GetCurrentThreadKey() << "] " << "UnlockParser" << std::endl;
+#endif // DEBUG_THREAD
     __UnLock(&m_ParseLock);
 }
 
 void ThreadManagement::LockStoreCommand(void)
 {
+#ifdef DEBUG_THREAD
+    std::cout << "[" << __GetCurrentThreadKey() << "] " << "LockStoreCommand" << std::endl;
+#endif // DEBUG_THREAD
     __Lock(&m_StoreCommandLock);
 }
 
 void ThreadManagement::UnlockStoreCommand(void)
 {
+#ifdef DEBUG_THREAD
+    std::cout << "[" << __GetCurrentThreadKey() << "] " << "UnlockStoreCommand" << std::endl;
+#endif // DEBUG_THREAD
     __UnLock(&m_StoreCommandLock);
 }
 
 void ThreadManagement::LockRunner(void)
 {
+#ifdef DEBUG_THREAD
+    std::cout << "[" << __GetCurrentThreadKey() << "] " << "LockRunner" << std::endl;
+#endif // DEBUG_THREAD
     __Lock(&m_RunnerLock);
 }
 
 void ThreadManagement::UnlockRunner(void)
 {
+#ifdef DEBUG_THREAD
+    std::cout << "[" << __GetCurrentThreadKey() << "] " << "UnlockRunner" << std::endl;
+#endif // DEBUG_THREAD
     __UnLock(&m_RunnerLock);
 }
 
 void ThreadManagement::SendAstPendingSignal(void)
 {
+#ifdef DEBUG_THREAD
+    std::cout << "[" << __GetCurrentThreadKey() << "] " << "SendAstPendingSignal" << std::endl;
+#endif // DEBUG_THREAD
     __LockSignal(&m_AstPendingLock);
+    m_AstPendingWasSignalled = true;
     __Signal(&m_AstPending);
     __UnLockSignal(&m_AstPendingLock);
 }
 
 void ThreadManagement::WaitForAstPendingSignal(void)
 {
+#ifdef DEBUG_THREAD
+    std::cout << "[" << __GetCurrentThreadKey() << "] " << "WaitForAstPendingSignal" << std::endl;
+#endif // DEBUG_THREAD
     __LockSignal(&m_AstPendingLock);
-    __Wait(&m_AstPending, &m_AstPendingLock);
+    m_AstPendingWasSignalled = false;
+    while (m_AstPendingWasSignalled == false)
+    {
+        __Wait(&m_AstPending, &m_AstPendingLock);
+    }
     __UnLockSignal(&m_AstPendingLock);
+
 }
 
 void ThreadManagement::SendConsoleExecDoneSignal(void)
 {
+#ifdef DEBUG_THREAD
+    std::cout << "[" << __GetCurrentThreadKey() << "] " << "SendConsoleExecDoneSignal" << std::endl;
+#endif // DEBUG_THREAD
     __LockSignal(&m_ConsoleExecDoneLock);
+    m_ConsoleExecDoneWasSignalled = true;
     __Signal(&m_ConsoleExecDone);
     __UnLockSignal(&m_ConsoleExecDoneLock);
 }
 
 void ThreadManagement::WaitForConsoleExecDoneSignal(void)
 {
+#ifdef DEBUG_THREAD
+    std::cout << "[" << __GetCurrentThreadKey() << "] " << "WaitForConsoleExecDoneSignal" << std::endl;
+#endif // DEBUG_THREAD
     __LockSignal(&m_ConsoleExecDoneLock);
-    __Wait(&m_ConsoleExecDone, &m_ConsoleExecDoneLock);
+    m_ConsoleExecDoneWasSignalled = false;
+    while (m_ConsoleExecDoneWasSignalled == false)
+    {
+        __Wait(&m_ConsoleExecDone, &m_ConsoleExecDoneLock);
+    }
     __UnLockSignal(&m_ConsoleExecDoneLock);
 }
 
 void ThreadManagement::SendAwakeRunnerSignal(void)
 {
+#ifdef DEBUG_THREAD
+    std::cout << "[" << __GetCurrentThreadKey() << "] " << "SendAwakeRunnerSignal" << std::endl;
+#endif // DEBUG_THREAD
     __LockSignal(&m_AwakeRunnerLock);
+    m_AwakeRunnerWasSignalled = true;
     __Signal(&m_AwakeRunner);
     __UnLockSignal(&m_AwakeRunnerLock);
 }
 
 void ThreadManagement::WaitForAwakeRunnerSignal(void)
 {
+#ifdef DEBUG_THREAD
+    std::cout << "[" << __GetCurrentThreadKey() << "] " << "WaitForAwakeRunnerSignal" << std::endl;
+#endif // DEBUG_THREAD
     __LockSignal(&m_AwakeRunnerLock);
     ThreadManagement::UnlockRunner();
-    __Wait(&m_AwakeRunner, &m_AwakeRunnerLock);
+    m_AwakeRunnerWasSignalled = false;
+    while (m_AwakeRunnerWasSignalled == false)
+    {
+        __Wait(&m_AwakeRunner, &m_AwakeRunnerLock);
+    }
     __UnLockSignal(&m_AwakeRunnerLock);
 }
 
 void ThreadManagement::SendStartPendingSignal(void)
 {
+#ifdef DEBUG_THREAD
+    std::cout << "[" << __GetCurrentThreadKey() << "] " << "SendStartPendingSignal" << std::endl;
+#endif // DEBUG_THREAD
     __LockSignal(&m_StartPendingLock);
+    m_StartPendingWasSignalled = true;
     __Signal(&m_StartPending);
     __UnLockSignal(&m_StartPendingLock);
 }
 
 void ThreadManagement::WaitForStartPendingSignal(void)
 {
+#ifdef DEBUG_THREAD
+    std::cout << "[" << __GetCurrentThreadKey() << "] " << "WaitForStartPendingSignal" << std::endl;
+#endif // DEBUG_THREAD
     __LockSignal(&m_StartPendingLock);
     ThreadManagement::UnlockStart();
-    __Wait(&m_StartPending, &m_StartPendingLock);
+    m_StartPendingWasSignalled = false;
+    while (m_StartPendingWasSignalled == false)
+    {
+        __Wait(&m_StartPending, &m_StartPendingLock);
+    }
     __UnLockSignal(&m_StartPendingLock);
 }
 
 void ThreadManagement::SendCommandStoredSignal(void)
 {
+#ifdef DEBUG_THREAD
+    std::cout << "[" << __GetCurrentThreadKey() << "] " << "SendCommandStoredSignal" << std::endl;
+#endif // DEBUG_THREAD
     __LockSignal(&m_CommandStoredLock);
+    m_CommandStoredWasSignalled = true;
     __Signal(&m_CommandStored);
     __UnLockSignal(&m_CommandStoredLock);
 }
 
 void ThreadManagement::WaitForCommandStoredSignal(void)
 {
+#ifdef DEBUG_THREAD
+    std::cout << "[" << __GetCurrentThreadKey() << "] " << "WaitForCommandStoredSignal" << std::endl;
+#endif // DEBUG_THREAD
     __LockSignal(&m_CommandStoredLock);
-    __Wait(&m_CommandStored, &m_CommandStoredLock);
+    m_CommandStoredWasSignalled = false;
+    while (m_CommandStoredWasSignalled == false)
+    {
+        __Wait(&m_CommandStored, &m_CommandStoredLock);
+    }
     __UnLockSignal(&m_CommandStoredLock);
 }
index 6fcf10c..ccbf19f 100644 (file)
@@ -72,12 +72,13 @@ int StoreConsoleCommand(char *command)
                                         /* is interruptible*/ 1,
                                         /* from console */ 1);
 
-    ThreadManagement::UnlockStoreCommand();
     // Awake Scilab to execute a new command
     ThreadManagement::SendCommandStoredSignal();
     // Awake Runner to execute this prioritary command
     ThreadManagement::SendAwakeRunnerSignal();
 
+    ThreadManagement::UnlockStoreCommand();
+
     return 0;
 }
 
@@ -89,12 +90,13 @@ int StorePrioritaryCommand(char *command)
                                         /* is interruptible*/ 0,
                                         /* from console */ 0);
 
-    ThreadManagement::UnlockStoreCommand();
     // Awake Scilab to execute a new command
     ThreadManagement::SendCommandStoredSignal();
     // Awake Runner to execute this prioritary command
     ThreadManagement::SendAwakeRunnerSignal();
 
+    ThreadManagement::UnlockStoreCommand();
+
     return 0;
 }