Lock to manage interruptible threads added. 47/16947/2
Cedric Delamarre [Fri, 31 Jul 2015 15:51:53 +0000 (17:51 +0200)]
Change-Id: I24ba52cd38cf391c4098089eb516d1631851ad31

scilab/modules/ast/includes/system_env/threadmanagement.hxx
scilab/modules/ast/src/cpp/ast/runvisitor.cpp
scilab/modules/ast/src/cpp/system_env/threadmanagement.cpp
scilab/modules/core/src/cpp/runner.cpp

index 5ada1b6..7b2cf69 100644 (file)
@@ -27,6 +27,7 @@ private :
     static __threadLock m_StartLock;
     static __threadLock m_ParseLock;
     static __threadLock m_StoreCommandLock;
+    static __threadLock m_AstLock;
 
     static __threadSignal m_ConsoleExecDone;
     static __threadSignalLock m_ConsoleExecDoneLock;
@@ -61,6 +62,8 @@ public :
     static void UnlockStoreCommand(void);
     static void LockRunner(void);
     static void UnlockRunner(void);
+    static void LockAst(void);
+    static void UnlockAst(void);
 
     static void SendAstPendingSignal(void);
     static void WaitForAstPendingSignal(void);
index edee8ca..9b0d8a4 100644 (file)
@@ -927,11 +927,14 @@ void RunVisitorT<T>::visitprivate(const SeqExp  &e)
             continue;
         }
 
+        ThreadManagement::LockAst();
         if (pThreadMe && pThreadMe->getInterrupt())
         {
             ThreadManagement::SendAstPendingSignal();
+            ThreadManagement::UnlockAst();
             pThreadMe->suspend();
         }
+        ThreadManagement::UnlockAst();
 
         try
         {
index 5e48603..6376b91 100644 (file)
@@ -21,6 +21,7 @@ __threadLock ThreadManagement::m_StartLock;
 __threadLock ThreadManagement::m_RunnerLock;
 __threadLock ThreadManagement::m_ParseLock;
 __threadLock ThreadManagement::m_StoreCommandLock;
+__threadLock ThreadManagement::m_AstLock;
 
 __threadSignal ThreadManagement::m_ConsoleExecDone;
 __threadSignalLock ThreadManagement::m_ConsoleExecDoneLock;
@@ -49,6 +50,7 @@ void ThreadManagement::initialize()
     __InitLock(&m_StartLock);
     __InitLock(&m_ParseLock);
     __InitLock(&m_StoreCommandLock);
+    __InitLock(&m_AstLock);
 
     __InitSignal(&m_AwakeRunner);
     __InitSignalLock(&m_AwakeRunnerLock);
@@ -130,6 +132,22 @@ void ThreadManagement::UnlockRunner(void)
     __UnLock(&m_RunnerLock);
 }
 
+void ThreadManagement::LockAst(void)
+{
+#ifdef DEBUG_THREAD
+    std::cout << "[" << __GetCurrentThreadKey() << "] " << "LockAst" << std::endl;
+#endif // DEBUG_THREAD
+    __Lock(&m_AstLock);
+}
+
+void ThreadManagement::UnlockAst(void)
+{
+#ifdef DEBUG_THREAD
+    std::cout << "[" << __GetCurrentThreadKey() << "] " << "UnlockAst" << std::endl;
+#endif // DEBUG_THREAD
+    __UnLock(&m_AstLock);
+}
+
 void ThreadManagement::SendAstPendingSignal(void)
 {
 #ifdef DEBUG_THREAD
@@ -147,6 +165,7 @@ void ThreadManagement::WaitForAstPendingSignal(void)
     std::cout << "[" << __GetCurrentThreadKey() << "] " << "WaitForAstPendingSignal" << std::endl;
 #endif // DEBUG_THREAD
     __LockSignal(&m_AstPendingLock);
+    ThreadManagement::UnlockAst();
     m_AstPendingWasSignalled = false;
     while (m_AstPendingWasSignalled == false)
     {
index 95b939c..5d8e127 100644 (file)
@@ -76,6 +76,7 @@ void *Runner::launch(void *args)
         bdoUnlock = true;
     }
 
+    ThreadManagement::LockAst();
     if (pThread->getInterrupt()) // non-prioritary
     {
         // Unlock prioritary thread waiting for
@@ -83,8 +84,10 @@ void *Runner::launch(void *args)
         // This case appear when error is throw or when
         // non-prioritary execute this last SeqExp.
         pThread->setInterrupt(false);
+        pThread->setInterruptible(false);
         ThreadManagement::SendAstPendingSignal();
     }
+    ThreadManagement::UnlockAst();
 
     if (pThread->isConsoleCommand())
     {
@@ -118,6 +121,7 @@ void Runner::execAndWait(ast::Exp* _theProgram, ast::ExecVisitor *_visitor,
         {
             if (pInterruptibleThread)
             {
+                ThreadManagement::LockAst();
                 if (pInterruptibleThread->isInterruptible())
                 {
                     pInterruptibleThread->setInterrupt(true);
@@ -125,6 +129,7 @@ void Runner::execAndWait(ast::Exp* _theProgram, ast::ExecVisitor *_visitor,
                 }
                 else
                 {
+                    ThreadManagement::UnlockAst();
                     __WaitThreadDie(pInterruptibleThread->getThreadId());
                     pInterruptibleThread = NULL;
                 }