Apply pthread_cancel_patch
This commit is contained in:
parent
72fcbc3ee6
commit
09cbb9d6b7
|
@ -1,3 +1,13 @@
|
||||||
|
2003-01-09 Thomas Pfaff <tpfaff@gmx.net>
|
||||||
|
|
||||||
|
* thread.h (WAIT_CANCELED): New define.
|
||||||
|
(pthread::cancelable_wait): New static method.
|
||||||
|
* thread.cc (pthread::cancelable_wait): Implement.
|
||||||
|
(semaphore::Wait): Wait on semaphore and thread cancellation.
|
||||||
|
(pthread::join): Wait on joined thread and thread cancellation.
|
||||||
|
(semaphore::wait): Add testcancel to check for thread
|
||||||
|
cancellation even if the semaphore is available.
|
||||||
|
|
||||||
2003-01-09 Thomas Pfaff <tpfaff@gmx.net>
|
2003-01-09 Thomas Pfaff <tpfaff@gmx.net>
|
||||||
|
|
||||||
* include/pthread.h: Add define for errorchecking mutexes.
|
* include/pthread.h: Add define for errorchecking mutexes.
|
||||||
|
|
|
@ -471,7 +471,7 @@ pwrite ()
|
||||||
read ()
|
read ()
|
||||||
readv ()
|
readv ()
|
||||||
select ()
|
select ()
|
||||||
sem_wait ()
|
*sem_wait ()
|
||||||
sigpause ()
|
sigpause ()
|
||||||
sigsuspend ()
|
sigsuspend ()
|
||||||
sigtimedwait ()
|
sigtimedwait ()
|
||||||
|
@ -632,6 +632,28 @@ pthread::static_cancel_self (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DWORD pthread::cancelable_wait (HANDLE object, DWORD timeout, const bool do_cancel)
|
||||||
|
{
|
||||||
|
DWORD res;
|
||||||
|
HANDLE wait_objects[2];
|
||||||
|
pthread_t thread = self ();
|
||||||
|
|
||||||
|
if (!isGoodObject (&thread) || thread->cancelstate == PTHREAD_CANCEL_DISABLE)
|
||||||
|
return WaitForSingleObject (object, timeout);
|
||||||
|
|
||||||
|
// Do not change the wait order
|
||||||
|
// The object must have higher priority than the cancel event,
|
||||||
|
// because WaitForMultipleObjects will return the smallest index
|
||||||
|
// if both objects are signaled
|
||||||
|
wait_objects[0] = object;
|
||||||
|
wait_objects[1] = thread->cancel_event;
|
||||||
|
|
||||||
|
res = WaitForMultipleObjects (2, wait_objects, FALSE, timeout);
|
||||||
|
if (do_cancel && res == WAIT_CANCELED)
|
||||||
|
pthread::static_cancel_self ();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pthread::setcancelstate (int state, int *oldstate)
|
pthread::setcancelstate (int state, int *oldstate)
|
||||||
{
|
{
|
||||||
|
@ -1390,8 +1412,15 @@ semaphore::TryWait ()
|
||||||
void
|
void
|
||||||
semaphore::Wait ()
|
semaphore::Wait ()
|
||||||
{
|
{
|
||||||
WaitForSingleObject (win32_obj_id, INFINITE);
|
switch (pthread::cancelable_wait (win32_obj_id, INFINITE))
|
||||||
currentvalue--;
|
{
|
||||||
|
case WAIT_OBJECT_0:
|
||||||
|
currentvalue--;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
debug_printf ("cancelable_wait failed. %E");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1850,14 +1879,15 @@ pthread::join (pthread_t *thread, void **return_val)
|
||||||
{
|
{
|
||||||
pthread_t joiner = self ();
|
pthread_t joiner = self ();
|
||||||
|
|
||||||
if (!isGoodObject (&joiner))
|
joiner->testcancel ();
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
// Initialize return val with NULL
|
// Initialize return val with NULL
|
||||||
if (return_val)
|
if (return_val)
|
||||||
*return_val = NULL;
|
*return_val = NULL;
|
||||||
|
|
||||||
/* FIXME: wait on the thread cancellation event as well - we are a cancellation point*/
|
if (!isGoodObject (&joiner))
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
if (!isGoodObject (thread))
|
if (!isGoodObject (thread))
|
||||||
return ESRCH;
|
return ESRCH;
|
||||||
|
|
||||||
|
@ -1876,14 +1906,26 @@ pthread::join (pthread_t *thread, void **return_val)
|
||||||
(*thread)->joiner = joiner;
|
(*thread)->joiner = joiner;
|
||||||
(*thread)->attr.joinable = PTHREAD_CREATE_DETACHED;
|
(*thread)->attr.joinable = PTHREAD_CREATE_DETACHED;
|
||||||
(*thread)->mutex.UnLock ();
|
(*thread)->mutex.UnLock ();
|
||||||
WaitForSingleObject ((*thread)->win32_obj_id, INFINITE);
|
|
||||||
if (return_val)
|
|
||||||
*return_val = (*thread)->return_ptr;
|
|
||||||
// cleanup
|
|
||||||
delete (*thread);
|
|
||||||
} /* End if */
|
|
||||||
|
|
||||||
pthread_testcancel ();
|
switch (cancelable_wait ((*thread)->win32_obj_id, INFINITE, false))
|
||||||
|
{
|
||||||
|
case WAIT_OBJECT_0:
|
||||||
|
if (return_val)
|
||||||
|
*return_val = (*thread)->return_ptr;
|
||||||
|
delete (*thread);
|
||||||
|
break;
|
||||||
|
case WAIT_CANCELED:
|
||||||
|
// set joined thread back to joinable since we got canceled
|
||||||
|
(*thread)->joiner = NULL;
|
||||||
|
(*thread)->attr.joinable = PTHREAD_CREATE_JOINABLE;
|
||||||
|
joiner->cancel_self ();
|
||||||
|
// never reached
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// should never happen
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2629,6 +2671,8 @@ semaphore::destroy (sem_t *sem)
|
||||||
int
|
int
|
||||||
semaphore::wait (sem_t *sem)
|
semaphore::wait (sem_t *sem)
|
||||||
{
|
{
|
||||||
|
pthread_testcancel ();
|
||||||
|
|
||||||
if (!isGoodObject (sem))
|
if (!isGoodObject (sem))
|
||||||
{
|
{
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
|
|
|
@ -332,6 +332,8 @@ private:
|
||||||
static nativeMutex mutexInitializationLock;
|
static nativeMutex mutexInitializationLock;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define WAIT_CANCELED (WAIT_OBJECT_0 + 1)
|
||||||
|
|
||||||
class pthread:public verifyable_object
|
class pthread:public verifyable_object
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -379,6 +381,8 @@ public:
|
||||||
virtual void testcancel ();
|
virtual void testcancel ();
|
||||||
static void static_cancel_self ();
|
static void static_cancel_self ();
|
||||||
|
|
||||||
|
static DWORD cancelable_wait (HANDLE object, DWORD timeout, const bool do_cancel = true);
|
||||||
|
|
||||||
virtual int setcancelstate (int state, int *oldstate);
|
virtual int setcancelstate (int state, int *oldstate);
|
||||||
virtual int setcanceltype (int type, int *oldtype);
|
virtual int setcanceltype (int type, int *oldtype);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue