License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
+#include <hurd/signal.h>
#include <pthread.h>
#include <pthreadP.h>
#include <pt-internal.h>
struct __pthread *p = _pthread_self ();
int oldtype;
+ HURD_CRITICAL_BEGIN;
__pthread_mutex_lock (&p->cancel_lock);
oldtype = p->cancel_type;
p->cancel_type = PTHREAD_CANCEL_ASYNCHRONOUS;
__pthread_mutex_unlock (&p->cancel_lock);
+ HURD_CRITICAL_END;
__pthread_testcancel ();
{
struct __pthread *p = _pthread_self ();
+ HURD_CRITICAL_BEGIN;
__pthread_mutex_lock (&p->cancel_lock);
p->cancel_type = oldtype;
__pthread_mutex_unlock (&p->cancel_lock);
+ HURD_CRITICAL_END;
}
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
+#include <hurd/signal.h>
#include <pthread.h>
#include <pt-internal.h>
{
int err = 0;
struct __pthread *p;
+ struct __pthread *self = _pthread_self ();
+ void *hurd_critical = NULL;
p = __pthread_getid (t);
if (p == NULL)
return ESRCH;
+ if (p == self)
+ hurd_critical = _hurd_critical_section_lock ();
+
__pthread_mutex_lock (&p->cancel_lock);
if (p->cancel_pending)
{
__pthread_mutex_unlock (&p->cancel_lock);
+ if (p == self)
+ _hurd_critical_section_unlock (hurd_critical);
return 0;
}
if (p->cancel_state != PTHREAD_CANCEL_ENABLE)
{
__pthread_mutex_unlock (&p->cancel_lock);
+ if (p == self)
+ _hurd_critical_section_unlock (hurd_critical);
return 0;
}
if (p->cancel_type == PTHREAD_CANCEL_ASYNCHRONOUS)
/* CANCEL_LOCK is unlocked by this call. */
- err = __pthread_do_cancel (p);
+ err = __pthread_do_cancel (p, hurd_critical);
else
{
if (p->cancel_hook != NULL)
__pthread_mutex_unlock (&p->cancel_lock);
}
+ if (p == self)
+ _hurd_critical_section_unlock (hurd_critical);
return err;
}
/* Perform a cancelation. The CANCEL_LOCK member of the given thread must
be locked before calling this function, which must unlock it. */
-extern int __pthread_do_cancel (struct __pthread *thread);
+extern int __pthread_do_cancel (struct __pthread *thread, void *hurd_critical);
/* Initialize the thread specific data structures. THREAD must be the
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
+#include <hurd/signal.h>
#include <pthread.h>
#include <shlib-compat.h>
#include <pt-internal.h>
break;
}
+ HURD_CRITICAL_BEGIN;
__pthread_mutex_lock (&p->cancel_lock);
if (oldstate != NULL)
*oldstate = p->cancel_state;
/* Do not achieve cancel when called again, notably from __pthread_exit itself. */
p->cancel_pending = 2;
__pthread_mutex_unlock (&p->cancel_lock);
+ HURD_CRITICAL_END;
if (cancelled)
__pthread_exit (PTHREAD_CANCELED);
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
+#include <hurd/signal.h>
#include <pthread.h>
#include <shlib-compat.h>
#include <pt-internal.h>
break;
}
+ HURD_CRITICAL_BEGIN;
__pthread_mutex_lock (&p->cancel_lock);
if (oldtype != NULL)
*oldtype = p->cancel_type;
p->cancel_type = type;
cancelled = (p->cancel_state == PTHREAD_CANCEL_ENABLE) && p->cancel_pending && (p->cancel_type == PTHREAD_CANCEL_ASYNCHRONOUS);
__pthread_mutex_unlock (&p->cancel_lock);
+ HURD_CRITICAL_END;
if (cancelled)
__pthread_exit (PTHREAD_CANCELED);
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
+#include <hurd/signal.h>
#include <pthread.h>
#include <pt-internal.h>
struct __pthread *p = _pthread_self ();
int cancelled;
+ HURD_CRITICAL_BEGIN;
__pthread_mutex_lock (&p->cancel_lock);
cancelled = (p->cancel_state == PTHREAD_CANCEL_ENABLE) && p->cancel_pending;
__pthread_mutex_unlock (&p->cancel_lock);
+ HURD_CRITICAL_END;
if (cancelled)
__pthread_exit (PTHREAD_CANCELED);
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
+#include <hurd/signal.h>
#include <pthread.h>
#include <shlib-compat.h>
#include <pt-internal.h>
This function contains inline implementations of pthread_testcancel and
pthread_setcanceltype to reduce locking overhead. */
+ HURD_CRITICAL_BEGIN;
__pthread_mutex_lock (&self->cancel_lock);
cancelled = (self->cancel_state == PTHREAD_CANCEL_ENABLE)
&& self->cancel_pending;
if (cancelled)
{
__pthread_mutex_unlock (&self->cancel_lock);
+ HURD_CRITICAL_UNLOCK;
__pthread_exit (PTHREAD_CANCELED);
}
__pthread_spin_unlock (&cond->__lock);
__pthread_mutex_unlock (&self->cancel_lock);
+ HURD_CRITICAL_END;
/* Increase the waiter reference count. Relaxed MO is sufficient because
we only need to synchronize when decrementing the reference count.
}
int
-__pthread_do_cancel (struct __pthread *p)
+__pthread_do_cancel (struct __pthread *p, void *hurd_critical)
{
+ struct __pthread *self = _pthread_self ();
mach_port_t ktid;
int me;
assert (p->cancel_state == PTHREAD_CANCEL_ENABLE);
__pthread_mutex_unlock (&p->cancel_lock);
+ if (p == self)
+ _hurd_critical_section_unlock (hurd_critical);
ktid = __mach_thread_self ();
me = p->kernel_thread == ktid;