Add autoconf checks for pthreads; fix #340
This commit is contained in:
1 parent
917334d18a
commit
d056668f4f
7 files changed
+155
-21
No files matched your search
+52
-20
@@ -7,13 +7,27 @@ struct nomem_handler {
|
||||
void *data;
|
||||
};
|
||||
|
||||
#ifndef USE_PTHREAD_KEY
|
||||
#ifdef _MSC_VER
|
||||
static __declspec(thread) struct nomem_handler nomem_handler;
|
||||
#else
|
||||
static __thread struct nomem_handler nomem_handler;
|
||||
#endif
|
||||
#if !defined(HAVE_PTHREAD_KEY_CREATE) || \
|
||||
!defined(HAVE_PTHREAD_ONCE) || \
|
||||
!defined(HAVE_ATEXIT)
|
||||
|
||||
/* Try thread-local storage? */
|
||||
|
||||
#ifdef _MSC_VER
|
||||
/* Visual C++: yes */
|
||||
static __declspec(thread) struct nomem_handler nomem_handler;
|
||||
#define USE_TLS
|
||||
#else
|
||||
#ifdef HAVE___THREAD
|
||||
/* GCC and friends: yes */
|
||||
static __thread struct nomem_handler nomem_handler;
|
||||
#define USE_TLS
|
||||
#endif /* HAVE___THREAD */
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
#endif /* !HAVE_PTHREAD_KEY_CREATE */
|
||||
|
||||
#ifdef USE_TLS
|
||||
void jv_nomem_handler(jv_nomem_handler_f handler, void *data) {
|
||||
nomem_handler.handler = handler;
|
||||
}
|
||||
@@ -25,44 +39,60 @@ static void memory_exhausted() {
|
||||
fprintf(stderr, "error: cannot allocate memory\n");
|
||||
abort();
|
||||
}
|
||||
#else
|
||||
#else /* USE_TLS */
|
||||
|
||||
#ifdef HAVE_PTHREAD_KEY_CREATE
|
||||
#include <pthread.h>
|
||||
|
||||
pthread_key_t nomem_handler_key;
|
||||
pthread_once_t mem_once = PTHREAD_ONCE_INIT;
|
||||
|
||||
static void tsd_fini(void) {
|
||||
struct nomem_handler *nomem_handler;
|
||||
nomem_handler = pthread_getspecific(nomem_handler_key);
|
||||
if (nomem_handler) {
|
||||
(void) pthread_setspecific(nomem_handler_key, NULL);
|
||||
free(nomem_handler);
|
||||
}
|
||||
}
|
||||
|
||||
static void tsd_init(void) {
|
||||
if (pthread_key_create(&nomem_handler_key, NULL) != 0) {
|
||||
fprintf(stderr, "error: cannot create thread specific key");
|
||||
abort();
|
||||
}
|
||||
if (atexit(tsd_fini) != 0) {
|
||||
fprintf(stderr, "error: cannot set an exit handler");
|
||||
abort();
|
||||
}
|
||||
struct nomem_handler *nomem_handler = calloc(1, sizeof(struct nomem_handler));
|
||||
if (pthread_setspecific(nomem_handler_key, nomem_handler) != 0) {
|
||||
fprintf(stderr, "error: cannot set thread specific data");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
void jv_nomem_handler(jv_nomem_handler_f handler, void *data) {
|
||||
pthread_once(&mem_once, tsd_init); // cannot fail
|
||||
struct nomem_handler *nomem_handler = calloc(1, sizeof (nomem_handler));
|
||||
struct nomem_handler *nomem_handler;
|
||||
|
||||
nomem_handler = pthread_getspecific(nomem_handler_key);
|
||||
if (nomem_handler == NULL) {
|
||||
handler(data);
|
||||
fprintf(stderr, "error: cannot allocate memory\n");
|
||||
abort();
|
||||
}
|
||||
nomem_handler.handler = handler;
|
||||
nomem_handler.data = data;
|
||||
if (pthread_setspecific(nomem_handler_key, nomem_handler) != 0) {
|
||||
handler(data);
|
||||
fprintf(stderr, "error: cannot set thread specific data");
|
||||
abort();
|
||||
}
|
||||
nomem_handler->handler = handler;
|
||||
nomem_handler->data = data;
|
||||
}
|
||||
|
||||
static void memory_exhausted() {
|
||||
jv_nomem_handler_f handler;
|
||||
struct nomem_handler *nomem_handler;
|
||||
|
||||
pthread_once(&mem_once, tsd_init);
|
||||
handler = pthread_getspecific(nomem_handler_key);
|
||||
if (handler)
|
||||
handler(); // Maybe handler() will longjmp() to safety
|
||||
nomem_handler = pthread_getspecific(nomem_handler_key);
|
||||
if (nomem_handler)
|
||||
nomem_handler->handler(nomem_handler->data); // Maybe handler() will longjmp() to safety
|
||||
// Or not
|
||||
fprintf(stderr, "error: cannot allocate memory\n");
|
||||
abort();
|
||||
@@ -70,6 +100,8 @@ static void memory_exhausted() {
|
||||
|
||||
#else
|
||||
|
||||
/* No thread-local storage of any kind that we know how to handle */
|
||||
|
||||
static struct nomem_handler nomem_handler;
|
||||
void jv_nomem_handler(jv_nomem_handler_f handler, void *data) {
|
||||
nomem_handler.handler = handler;
|
||||
@@ -82,7 +114,7 @@ static void memory_exhausted() {
|
||||
}
|
||||
|
||||
#endif /* HAVE_PTHREAD_KEY_CREATE */
|
||||
#endif /* !USE_PTHREAD_KEY */
|
||||
#endif /* USE_TLS */
|
||||
|
||||
|
||||
void* jv_mem_alloc(size_t sz) {
|
||||
|
||||
Reference in new issue
Block a user