Browse Source

Fixing exit crash on Windows when canceling bake

Josh Engebretson 8 years ago
parent
commit
86c068ac58

+ 27 - 0
Source/Atomic/Core/Thread.cpp

@@ -156,4 +156,31 @@ bool Thread::IsMainThread()
 #endif // ATOMIC_THREADING
 }
 
+// ATOMIC BEGIN
+
+void Thread::Kill()
+{
+#ifdef ATOMIC_THREADING
+#ifdef ATOMIC_PLATFORM_WINDOWS
+    if (handle_)
+    {
+        DWORD exitCode = EXIT_SUCCESS;
+        TerminateThread((HANDLE)handle_, exitCode);
+    }
+#elif defined(ATOMIC_PLATFORM_OSX) 
+
+    ATOMIC_LOGINFO("Thread::Kill() - macOS implementation required");
+
+#elif defined(ATOMIC_PLATFORM_LINUX)
+    pthread_t* thread = (pthread_t*)handle_;
+    if (thread)
+    {
+        pthread_cancel(*thread);
+    }
+#endif
+#endif // ATOMIC_THREADING
+}
+
+// ATOMIC END
+
 }

+ 4 - 0
Source/Atomic/Core/Thread.h

@@ -63,6 +63,10 @@ public:
     /// Return whether is executing in the main thread.
     static bool IsMainThread();
 
+    // ATOMIC BEGIN
+    void Kill();
+    // ATOMIC END
+
 protected:
     /// Thread handle.
     void* handle_;

+ 14 - 0
Source/Atomic/Core/WorkQueue.cpp

@@ -423,4 +423,18 @@ void WorkQueue::HandleBeginFrame(StringHash eventType, VariantMap& eventData)
     PurgePool();
 }
 
+// ATOMIC BEGIN
+
+
+void WorkQueue::TerminateThreads()
+{
+    for (unsigned i = 0; i < threads_.Size(); ++i)
+        threads_[i]->Kill();
+
+    threads_.Clear();
+
+}
+
+// ATOMIC END
+
 }

+ 7 - 0
Source/Atomic/Core/WorkQueue.h

@@ -123,6 +123,13 @@ public:
     /// Return how many milliseconds maximum to spend on non-threaded low-priority work.
     int GetNonThreadedWorkMs() const { return maxNonThreadedWorkMs_; }
 
+    // ATOMIC_BEGIN
+
+    /// Terminates all worker threads, only use at exit
+    void TerminateThreads();
+
+    // ATOMIC END
+
 private:
     /// Process work items until shut down. Called by the worker threads.
     void ProcessItems(unsigned threadIndex);

+ 1 - 0
Source/AtomicGlow/GlowApplication/AtomicGlowApp.cpp

@@ -109,6 +109,7 @@ namespace AtomicGlow
         if (cmd == "quit")
         {
             ATOMIC_LOGINFO("AtomicGlow quit received, exiting");
+            GetSubsystem<WorkQueue>()->TerminateThreads();
             exitCode_ = EXIT_SUCCESS;
             engine_->Exit();
         }