minfrin 2004/09/19 12:15:12
Modified: . CHANGES
threadproc/win32 thread.c
Log:
Makes the threads to behave like on posix. If the thread is created without
APR_DETACH expect that the thread_join will be called, so don't close the
handle in advance, if the thread has already finished.
Submitted by: mturk
Reviewed by: wrowe
Revision Changes Path
1.491 +5 -0 apr/CHANGES
Index: CHANGES
===================================================================
RCS file: /home/cvs/apr/CHANGES,v
retrieving revision 1.490
retrieving revision 1.491
diff -u -r1.490 -r1.491
--- CHANGES 19 Sep 2004 17:44:17 -0000 1.490
+++ CHANGES 19 Sep 2004 19:15:12 -0000 1.491
@@ -1,5 +1,10 @@
Changes for APR 1.1 [Deferring these features when 1.0 is rolled out.]
+ *) Makes the threads to behave like on posix. If the thread is created
+ without APR_DETACH expect that the thread_join will be called, so don't
+ close the handle in advance, if the thread has already finished.
+ [Mladen Turk]
+
*) The apr/test/Makefile.win is missing a target to build a
readchild.exe that test is depending on but is never built.
[Mladen Turk]
1.58 +26 -15 apr/threadproc/win32/thread.c
Index: thread.c
===================================================================
RCS file: /home/cvs/apr/threadproc/win32/thread.c,v
retrieving revision 1.57
retrieving revision 1.58
diff -u -r1.57 -r1.58
--- thread.c 10 Jun 2004 10:57:25 -0000 1.57
+++ thread.c 19 Sep 2004 19:15:12 -0000 1.58
@@ -85,6 +85,7 @@
{
apr_status_t stat;
unsigned temp;
+ HANDLE handle;
(*new) = (apr_thread_t *)apr_palloc(pool, sizeof(apr_thread_t));
@@ -95,7 +96,7 @@
(*new)->pool = pool;
(*new)->data = data;
(*new)->func = func;
-
+ (*new)->td = NULL;
stat = apr_pool_create(&(*new)->pool, pool);
if (stat != APR_SUCCESS) {
return stat;
@@ -105,14 +106,14 @@
* same size as the calling thread.
*/
#ifndef _WIN32_WCE
- if (((*new)->td = (HANDLE)_beginthreadex(NULL,
+ if ((handle = (HANDLE)_beginthreadex(NULL,
attr && attr->stacksize > 0 ? attr->stacksize : 0,
(unsigned int (APR_THREAD_FUNC *)(void
*))dummy_worker,
(*new), 0, &temp)) == 0) {
return APR_FROM_OS_ERROR(_doserrno);
}
#else
- if (((*new)->td = CreateThread(NULL,
+ if ((handle = CreateThread(NULL,
attr && attr->stacksize > 0 ? attr->stacksize : 0,
(unsigned int (APR_THREAD_FUNC *)(void
*))dummy_worker,
(*new), 0, &temp)) == 0) {
@@ -120,9 +121,10 @@
}
#endif
if (attr && attr->detach) {
- CloseHandle((*new)->td);
- (*new)->td = NULL;
+ CloseHandle(handle);
}
+ else
+ (*new)->td = handle;
return APR_SUCCESS;
}
@@ -132,10 +134,8 @@
{
thd->exitval = retval;
apr_pool_destroy(thd->pool);
+ thd->pool = NULL;
#ifndef _WIN32_WCE
- if (thd->td) {
- CloseHandle(thd->td);
- }
_endthreadex(0);
#else
ExitThread(0);
@@ -146,15 +146,26 @@
APR_DECLARE(apr_status_t) apr_thread_join(apr_status_t *retval,
apr_thread_t *thd)
{
- apr_status_t rv;
-
+ apr_status_t rv = APR_SUCCESS;
+
+ if (!thd->td) {
+ /* Can not join on detached threads */
+ return APR_DETACH;
+ }
rv = WaitForSingleObject(thd->td, INFINITE);
if ( rv == WAIT_OBJECT_0 || rv == WAIT_ABANDONED) {
- *retval = thd->exitval;
- return APR_SUCCESS;
- }
- /* Wait failed */
- return apr_get_os_error();;
+ /* If the thread_exit has been called */
+ if (!thd->pool)
+ *retval = thd->exitval;
+ else
+ rv = APR_INCOMPLETE;
+ }
+ else
+ rv = apr_get_os_error();
+ CloseHandle(thd->td);
+ thd->td = NULL;
+
+ return rv;
}
APR_DECLARE(apr_status_t) apr_thread_detach(apr_thread_t *thd)