htl: Add support for libc cancellation points

This commit is contained in:
Samuel Thibault 2020-02-09 22:23:52 +00:00
parent f1cd3407e4
commit 59b7fe99f2
6 changed files with 69 additions and 3 deletions

View file

@ -132,6 +132,7 @@ libpthread-routines := pt-attr pt-attr-destroy pt-attr-getdetachstate \
\
shm-directory \
\
cancellation \
cthreads-compat \
herrno \
$(SYSDEPS)

View file

@ -168,6 +168,8 @@ libpthread {
__pthread_mutex_init;
__pthread_mutex_destroy;
__pthread_mutex_timedlock;
__pthread_enable_asynccancel;
__pthread_disable_asynccancel;
_pthread_mutex_lock; _pthread_mutex_trylock; _pthread_mutex_unlock;
_pthread_rwlock_destroy; _pthread_rwlock_init;

45
htl/cancellation.c Normal file
View file

@ -0,0 +1,45 @@
/* Set the cancel type during blocking calls.
Copyright (C) 2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#include <pthread.h>
#include <pthreadP.h>
#include <pt-internal.h>
int __pthread_enable_asynccancel (void)
{
struct __pthread *p = _pthread_self ();
int oldtype;
__pthread_mutex_lock (&p->cancel_lock);
oldtype = p->cancel_type;
p->cancel_type = PTHREAD_CANCEL_ASYNCHRONOUS;
__pthread_mutex_unlock (&p->cancel_lock);
__pthread_testcancel ();
return oldtype;
}
void __pthread_disable_asynccancel (int oldtype)
{
struct __pthread *p = _pthread_self ();
__pthread_mutex_lock (&p->cancel_lock);
p->cancel_type = oldtype;
__pthread_mutex_unlock (&p->cancel_lock);
}

View file

@ -22,7 +22,7 @@
#include <pthreadP.h>
void
pthread_testcancel (void)
__pthread_testcancel (void)
{
struct __pthread *p = _pthread_self ();
int cancelled;
@ -34,3 +34,4 @@ pthread_testcancel (void)
if (cancelled)
__pthread_exit (PTHREAD_CANCELED);
}
strong_alias (__pthread_testcancel, pthread_testcancel)

View file

@ -84,6 +84,7 @@ int __pthread_attr_setstacksize (pthread_attr_t *__attr, size_t __stacksize);
int __pthread_attr_setstack (pthread_attr_t *__attr, void *__stackaddr,
size_t __stacksize);
int __pthread_attr_getstack (const pthread_attr_t *, void **, size_t *);
void __pthread_testcancel (void);
#if IS_IN (libpthread)
hidden_proto (__pthread_key_create)

View file

@ -1,8 +1,24 @@
#include <sysdep.h>
int __pthread_enable_asynccancel (void);
void __pthread_disable_asynccancel (int oldtype);
#pragma weak __pthread_enable_asynccancel
#pragma weak __pthread_disable_asynccancel
/* Always multi-thread (since there's at least the sig handler), but no
handling enabled. */
#define SINGLE_THREAD_P (0)
#define RTLD_SINGLE_THREAD_P (0)
#define LIBC_CANCEL_ASYNC() 0 /* Just a dummy value. */
#define LIBC_CANCEL_RESET(val) ((void)(val)) /* Nothing, but evaluate it. */
#define LIBC_CANCEL_ASYNC() ({ \
int __cancel_oldtype = 0; \
if (__pthread_enable_asynccancel) \
__cancel_oldtype = __pthread_enable_asynccancel(); \
__cancel_oldtype; \
})
#define LIBC_CANCEL_RESET(val) do { \
if (__pthread_disable_asynccancel) \
__pthread_disable_asynccancel (val); \
} while (0)