Fix broken thread stop handling
authorsapier <Sapier at GMX dot net>
Sat, 30 Nov 2013 00:51:54 +0000 (01:51 +0100)
committersapier <Sapier at GMX dot net>
Sat, 30 Nov 2013 01:15:31 +0000 (02:15 +0100)
src/jthread/jthread.h
src/jthread/pthread/jthread.cpp
src/jthread/win32/jthread.cpp
src/script/lua_api/l_async_events.cpp
src/script/lua_api/l_async_events.h

index 92b05f1c51cfb6f538636e272ce70e468f2049a4..867701c75f2f8c53e03e509948dbea5f0fbb8b26 100644 (file)
@@ -47,6 +47,7 @@ public:
        int Kill();
        virtual void *Thread() = 0;
        bool IsRunning();
+       bool StopRequested();
        void *GetReturnValue();
        bool IsSameThread();
 protected:
@@ -69,6 +70,7 @@ private:
 #endif // WIN32
        void *retval;
        bool running;
+       bool requeststop;
 
        JMutex runningmutex;
        JMutex continuemutex,continuemutex2;
index 2980e26b1cf447cf8a82219099aceacd2eaad0ae..c4d9162c8b47a5cda69ebc139e481906270f91ad 100644 (file)
@@ -34,6 +34,7 @@ JThread::JThread()
 {
        retval = NULL;
        mutexinit = false;
+       requeststop = false;
        running = false;
 }
 
@@ -44,7 +45,7 @@ JThread::~JThread()
 
 void JThread::Stop() {
        runningmutex.Lock();
-       running = false;
+       requeststop = true;
        runningmutex.Unlock();
 }
 
@@ -78,6 +79,7 @@ int JThread::Start()
                runningmutex.Unlock();
                return ERR_JTHREAD_ALREADYRUNNING;
        }
+       requeststop = false;
        runningmutex.Unlock();
 
        pthread_attr_t attr;
@@ -141,6 +143,15 @@ bool JThread::IsRunning()
        return r;
 }
 
+bool JThread::StopRequested() {
+       bool r;
+
+       runningmutex.Lock();
+       r = requeststop;
+       runningmutex.Unlock();
+       return r;
+}
+
 void *JThread::GetReturnValue()
 {
        void *val;
index 1cf4f93a3c8b57967c2f2391a980b1d156da208e..e56c1627109edc553ff0093e3c4cd07b203c1457 100644 (file)
@@ -35,6 +35,7 @@ JThread::JThread()
 {
        retval = NULL;
        mutexinit = false;
+       requeststop = false;
        running = false;
 }
 
@@ -45,7 +46,7 @@ JThread::~JThread()
 
 void JThread::Stop() {
        runningmutex.Lock();
-       running = false;
+       requeststop = false;
        runningmutex.Unlock();
 }
 
@@ -76,6 +77,7 @@ int JThread::Start()
                runningmutex.Unlock();
                return ERR_JTHREAD_ALREADYRUNNING;
        }
+       requeststop = false;e
        runningmutex.Unlock();
 
        continuemutex.Lock();
@@ -134,6 +136,15 @@ bool JThread::IsRunning()
        return r;
 }
 
+bool JThread::StopRequested() {
+       bool r;
+
+       runningmutex.Lock();
+       r = requeststop;
+       runningmutex.Unlock();
+       return r;
+}
+
 void *JThread::GetReturnValue()
 {
        void *val;
index cc4644cdfb617cb35ce87f50da2a243552b00c19..63ca87aed5fa34a34f7c2bfbb00255e5620f6c26 100644 (file)
@@ -149,9 +149,11 @@ LuaJobInfo AsyncEngine::getJob() {
        m_JobQueueMutex.Lock();
 
        LuaJobInfo retval;
+       retval.valid = false;
 
        if (m_JobQueue.size() != 0) {
                retval = m_JobQueue.front();
+               retval.valid = true;
                m_JobQueue.erase((m_JobQueue.begin()));
        }
        m_JobQueueMutex.Unlock();
@@ -322,11 +324,12 @@ void* AsyncWorkerThread::worker_thread_main() {
                        assert("no future with broken builtin async environment scripts" == 0);
        }
        /** main loop **/
-       while(IsRunning()) {
+       while(!StopRequested()) {
                //wait for job
                LuaJobInfo toprocess = m_JobDispatcher->getJob();
 
-               if (!IsRunning()) { continue; }
+               if (toprocess.valid == false) { continue; }
+               if (StopRequested()) { continue; }
 
                //first push error handler
                lua_pushcfunction(m_LuaStack, script_error_handler);
@@ -350,7 +353,7 @@ void* AsyncWorkerThread::worker_thread_main() {
                                                toprocess.serializedParams.c_str(),
                                                toprocess.serializedParams.length());
 
-               if (!IsRunning()) { continue; }
+               if (StopRequested()) { continue; }
                if(lua_pcall(m_LuaStack, 2, 2, errorhandler)) {
                        scriptError("Async WORKER thread: %s\n", lua_tostring(m_LuaStack, -1));
                        toprocess.serializedResult="ERROR";
@@ -362,7 +365,7 @@ void* AsyncWorkerThread::worker_thread_main() {
                        toprocess.serializedResult = std::string(retval,lenght);
                }
 
-               if (!IsRunning()) { continue; }
+               if (StopRequested()) { continue; }
                //put job result
                m_JobDispatcher->putJobResult(toprocess);
        }
index 347d9c0fcc9d71907db5e53769815c2db1e0da70..079a08009b7a7da61f5c71348d0a48b981021c24 100644 (file)
@@ -57,6 +57,8 @@ struct LuaJobInfo {
        std::string serializedResult;
        /** jobid used to identify a job and match it to callback **/
        unsigned int JobId;
+       /** valid marker **/
+       bool valid;
 };
 
 /** class encapsulating a asynchronous working environment **/