Merge pull request #206 from andrey-malets/avoid-pthread-cancel
Avoid pthread_cancel as it may not be defined.
This commit is contained in:
@ -340,6 +340,7 @@ isatty \
|
||||
memalign \
|
||||
memset \
|
||||
posix_memalign \
|
||||
pthread_cancel \
|
||||
pthread_yield \
|
||||
setvbuf \
|
||||
sqrt \
|
||||
|
||||
@ -33,6 +33,10 @@
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_PTHREAD_CANCEL
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
#include "sb_thread.h"
|
||||
#include "sb_rand.h"
|
||||
#include "sb_logger.h"
|
||||
@ -84,10 +88,61 @@ void sb_thread_done(void)
|
||||
free(threads);
|
||||
}
|
||||
|
||||
#ifndef HAVE_PTHREAD_CANCEL
|
||||
#define PTHREAD_CANCELED ((void *) -1)
|
||||
|
||||
struct sb_thread_proxy {
|
||||
void *(*start_routine) (void *);
|
||||
void *arg;
|
||||
};
|
||||
|
||||
static int thread_cancel_signal = SIGUSR1;
|
||||
|
||||
static void thread_cancel_handler(int sig)
|
||||
{
|
||||
if (sig == thread_cancel_signal)
|
||||
pthread_exit(PTHREAD_CANCELED);
|
||||
}
|
||||
|
||||
static int install_thread_signal_handler(void) {
|
||||
struct sigaction action;
|
||||
memset(&action, 0, sizeof(action));
|
||||
sigemptyset(&action.sa_mask);
|
||||
action.sa_flags = 0;
|
||||
action.sa_handler = thread_cancel_handler;
|
||||
return sigaction(thread_cancel_signal, &action, NULL);
|
||||
}
|
||||
|
||||
static void* thread_start_routine_proxy(void *arg) {
|
||||
struct sb_thread_proxy *proxy = arg;
|
||||
void *(*start_routine) (void *) = proxy->start_routine;
|
||||
void *real_arg = proxy->arg;
|
||||
free(proxy);
|
||||
install_thread_signal_handler();
|
||||
return start_routine(real_arg);
|
||||
}
|
||||
#endif
|
||||
|
||||
int sb_thread_create(pthread_t *thread, const pthread_attr_t *attr,
|
||||
void *(*start_routine) (void *), void *arg)
|
||||
{
|
||||
#ifdef HAVE_PTHREAD_CANCEL
|
||||
return pthread_create(thread, attr, start_routine, arg);
|
||||
#else
|
||||
struct sb_thread_proxy *proxy = malloc(sizeof(struct sb_thread_proxy));
|
||||
if (!proxy)
|
||||
{
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
proxy->start_routine = start_routine;
|
||||
proxy->arg = arg;
|
||||
int rv = pthread_create(thread, attr, thread_start_routine_proxy, proxy);
|
||||
if (rv)
|
||||
{
|
||||
free(proxy);
|
||||
}
|
||||
return rv;
|
||||
#endif
|
||||
}
|
||||
|
||||
int sb_thread_join(pthread_t thread, void **retval)
|
||||
@ -97,7 +152,11 @@ int sb_thread_join(pthread_t thread, void **retval)
|
||||
|
||||
int sb_thread_cancel(pthread_t thread)
|
||||
{
|
||||
#ifdef HAVE_PTHREAD_CANCEL
|
||||
return pthread_cancel(thread);
|
||||
#else
|
||||
return pthread_kill(thread, thread_cancel_signal);
|
||||
#endif
|
||||
}
|
||||
|
||||
int sb_thread_create_workers(void *(*worker_routine)(void*))
|
||||
|
||||
Reference in New Issue
Block a user