[Wesnoth-cvs-commits] wesnoth/src thread.cpp (June 03, 2005 - 02:55)

 

CVSROOT:	/cvsroot/wesnoth
Module name:	wesnoth
Branch: 	
Changes by:	David White <Sirp@xxxxxxxxxxxxxxxx>	05/06/03 00:44:28

Modified files:
	src            : thread.cpp 

Log message:
	fixed problem with network threads deadlocking

CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/wesnoth/wesnoth/src/thread.cpp.diff?tr1=1.6&tr2=1.7&r1=text&r2=text

Patches:
Index: wesnoth/src/thread.cpp
diff -u wesnoth/src/thread.cpp:1.6 wesnoth/src/thread.cpp:1.7
--- wesnoth/src/thread.cpp:1.6	Thu Jun  2 23:58:01 2005
+++ wesnoth/src/thread.cpp	Fri Jun  3 00:44:28 2005
@@ -2,6 +2,7 @@
 
 #include "thread.hpp"
 
+#include <new>
 #include <iostream>
 #include <vector>
 
@@ -25,6 +26,7 @@
 		delete op;
 	}
 
+
 	return 0;
 }
 
@@ -130,21 +132,37 @@
 
 async_operation::RESULT async_operation::execute(waiter& wait)
 {
-	const lock l(get_mutex());
-	thread t(run_async_operation,this);
+	//the thread must be created after the lock, and also destroyed after it.
+	//this is because during the thread's execution, we must always hold the mutex
+	//unless we are waiting on notification that the thread is finished, or we have
+	//already received that notification.
+	//
+	//we cannot hold the mutex while waiting for the thread to join though, because
+	//the thread needs access to the mutex before it terminates
+	std::auto_ptr<thread> t(NULL);
+	{
+		const lock l(get_mutex());
+		t = std::auto_ptr<thread>(new thread(run_async_operation,this));
+
+		bool completed = false;
+		while(wait.process() == waiter::WAIT) {
+			const condition::WAIT_TIMEOUT_RESULT res = finished_.wait_timeout(get_mutex(),20);
+			if(res == condition::WAIT_OK) {
+				completed = true;
+				break;
+			} else if(res == condition::WAIT_ERROR) {
+				break;
+			}
+		}
 
-	while(wait.process() == waiter::WAIT) {
-		const condition::WAIT_TIMEOUT_RESULT res = finished_.wait_timeout(get_mutex(),20);
-		if(res == condition::WAIT_OK) {
-			return COMPLETED;
-		} else if(res == condition::WAIT_ERROR) {
-			break;
+		if(!completed) {
+			aborted_ = true;
+			t->detach();
+			return ABORTED;
 		}
 	}
 
-	aborted_ = true;
-	t.detach();
-	return ABORTED;
+	return COMPLETED;
 }
 
 



You are on the gna.org mail server.

Generated by mhonarc, Tue Sep 20 16:50:21 2005