Patch is rather small (attached). Mind if I put it in? With this patch one can define any destruction policy for their threads:1. Thread object is destroyed externally. If it's in polite mode, destructor will terminate it 2. Thread object self-destructs: Derived object overrides onThreadExit() function and calls
delete (this) in there. Ilya A. Volynets-Evenbakh wrote:
Well, It's about time we go back to exploring this issue.I'm doing some testing in CPPSERv, and it's obvious that if we don't make the changes,nothing is going to work right.I think I'll go ahead and get rid of m_waiter lock alltogether and replace it with pthread_join for *nix, and put big fat error message for Winblows, so that everyone who runs threaded codeknows to bug you to fix polite thread destruction there. OK? Alexey Parshin wrote:It could be WaitForSingleObject(), but I'm not sure. I just never explored it.On 5/21/05, Ilya A. Volynets-Evenbakh <ilya@total-knowledge.com> wrote:Alexey Parshin wrote:Not that I know of ..Are you saing there is not way to say "block till thread completes" natively??However, in Windows CThread is an object, and I wonder how WaitForSingleObject would work with the thread.. It could be an idea.You really need to investigate that.On 5/21/05, Ilya A. Volynets-Evenbakh <ilya@total-knowledge.com> wrote:I think polite mode (at least on Unix) should be handled by pthread_join, and not the CWaiter. Is there similar concept in Winblows? Alexey Parshin wrote:I do use self-destruction sometimes. However that conception is limiting us too much. It should be another solution. In the worst possible case, we can drop onThreadExit() whatsoever.On 5/20/05, Ilya A. Volynets-Evenbakh <ilya@total-knowledge.com> wrote:I've been thinking about CThread::onThreadExit() function, and realized there is race condition there: thread a creates and starts thread b thread b is executing thread a calls b.terminate() thread b finishes executing threadFunction thread a destroyes thread b object. thread b.onThreadExit() starts executing This will happen even in polite mode, I'm afraid, since onThreadExit is called after m_waiter is unlocked.The only way to make sure this doesn't happen, that I can think of rightnow,is to impose "self-destruction" paradigm on CThread-derived objects.i.e. 1. CThread is always created on heap 2. CThread objects are never explicitly deleted. 3. there is onExitInternal() handler, that is called after normal onThreadExit() is called, and that does "delete this". This is serious change in usage paradigm, so before going ahead and making such a radical change, I want to know what you think about it all.oO(Perhaps HSquirrel is already using self-destuction paradigm anyways,like I do?) -- Ilya A. Volynets-Evenbakh Total Knowledge. CTO http://www.total-knowledge.com-- Ilya A. Volynets-Evenbakh Total Knowledge. CTO http://www.total-knowledge.com-- Ilya A. Volynets-Evenbakh Total Knowledge. CTO http://www.total-knowledge.com
-- Ilya A. Volynets-Evenbakh Total Knowledge. CTO http://www.total-knowledge.com
? autom4te.cache
? buildd
? thread.diff
? updt.log
Index: sptk3/CThread.h
===================================================================
RCS file: /cvsroot/sptk/sptk2/sptk3/CThread.h,v
retrieving revision 1.1
diff -u -r1.1 CThread.h
--- sptk3/CThread.h 25 Sep 2005 08:30:11 -0000 1.1
+++ sptk3/CThread.h 26 Sep 2005 05:24:14 -0000
@@ -39,7 +39,6 @@
bool m_running; ///< Flag: is the thread running?
bool m_politeMode; ///< Flag: does the thread uses the 'polite' mode for shutdown?
std::string m_name; ///< Thread name
- CWaiter m_waiter; ///< The synchronization object
#ifndef _WIN32
pthread_t m_thread; ///< Thread handle
#else
Index: src/CThread.cpp
===================================================================
RCS file: /cvsroot/sptk/sptk2/src/CThread.cpp,v
retrieving revision 1.8
diff -u -r1.8 CThread.cpp
--- src/CThread.cpp 25 Sep 2005 08:47:11 -0000 1.8
+++ src/CThread.cpp 26 Sep 2005 05:24:14 -0000
@@ -62,14 +62,7 @@
}
CThread::~CThread() {
- //printf("CThread::~CThread() for %s started.\n",m_name);
- if (m_running && m_politeMode) {
- // wait till the thread is stopping
- //printf("CThread::~CThread() for %s waiting politely.\n",m_name);
- m_waiter.lock();
- m_waiter.unlock();
- }
- //printf("CThread::~CThread() for %s ended.\n",m_name);
+ terminate();
}
void CThread::terminate() {
@@ -77,9 +70,15 @@
m_terminated = true;
if (m_running && m_politeMode) {
+#ifndef _WIN32
// wait till the thread is stopping
- m_waiter.lock();
- m_waiter.unlock();
+ pthread_join(m_thread,0);
+#else
+#warning BIG FAT WARNING: Alexey Parshin still did not implement propper polite thread termination!
+#warning Bug him _NOW_
+ fprintf(stderr, "BIG FAT WARNING: Alexey Parshin still did not implement propper polite thread termination!\n");
+ fprintf(stderr, "Bug him _NOW_\n");
+#endif
}
}
@@ -106,18 +105,9 @@
void CThread::runThread() {
m_terminated = false;
m_running = true;
-
- if (m_politeMode)
- m_waiter.lock();
-
threadFunction();
-
- if (m_politeMode)
- m_waiter.unlock();
-
- destroyThread();
-
m_running = false;
+ destroyThread();
}
void CThread::run() {
List hosted by Total Knowledge