72 #include <openssl/err.h>    78 #define THREADTABLE_SIZE 4096   107 #define THREAD(t) (threadtable[(t) % THREADTABLE_SIZE])   137         panic(ret, 
"gwthread-pthread: could not lock thread table");
   147         panic(ret, 
"gwthread-pthread: could not unlock thread table");
   155     unsigned char buf[128];
   159         bytes = read(fd, buf, 
sizeof(buf));
   186     if (pipe(pipefds) < 0) {
   187         error(errno, 
"cannot allocate wakeup pipe for new thread");
   224         panic(0, 
"gwthread-pthread: pthread_getspecific failed");
   239     pthread_cond_t *joiner_cond;
   245         pthread_cond_broadcast(joiner_cond);
   274     ret = pthread_key_create(&
tsd_key, NULL);
   276         panic(ret, 
"gwthread-pthread: pthread_key_create failed");
   286         panic(0, 
"gwthread-pthread: unable to fill main threadinfo.");
   290         panic(ret, 
"gwthread-pthread: pthread_setspecific failed");
   311             debug(
"gwlib", 0, 
"Thread %ld (%s) still running",
   325         warning(ret, 
"cannot destroy threadtable lock");
   337     debug(
"gwlib.gwthread", 0, 
"Thread %ld (%s) terminates.",
   341 #if OPENSSL_VERSION_NUMBER < 0x10100000L   379     ret = pthread_setspecific(
tsd_key, p->
ti);
   381         panic(ret, 
"gwthread-pthread: pthread_setspecific failed");
   384     p->
ti->
pid = getpid();
   385     debug(
"gwlib.gwthread", 0, 
"Thread %ld (%s) maps to pid %ld.",
   393     pthread_cleanup_pop(0);
   411 #if defined(DARWIN_OLD)   412     static int pthread_sigmask();
   418     sigset_t block_signals;
   420     ret = sigemptyset(&block_signals);
   422         error(errno, 
"gwthread-pthread: Couldn't initialize signal set");
   425     ret = sigaddset(&block_signals, SIGHUP);
   426     ret |= sigaddset(&block_signals, SIGTERM);
   427     ret |= sigaddset(&block_signals, SIGQUIT);
   428     ret |= sigaddset(&block_signals, SIGINT);
   430         error(0, 
"gwthread-pthread: Couldn't add signal to signal set");
   433     ret = pthread_sigmask(SIG_BLOCK, &block_signals, old_set_storage);
   436             "gwthread-pthread: Couldn't disable signals for thread creation");
   446     ret = pthread_sigmask(SIG_SETMASK, old_set, NULL);
   448         panic(ret, 
"gwthread-pthread: Couldn't restore signal set.");
   463     p = gw_malloc(
sizeof(*p));
   466     p->
ti = gw_malloc(
sizeof(*(p->
ti)));
   476         error(0, 
"Too many threads, could not create new thread.");
   482     ret = pthread_create(&
id, NULL, &
new_thread, p);
   485         error(ret, 
"Could not create new thread.");
   490     ret = pthread_detach(
id);
   492         error(ret, 
"Could not detach new thread.");
   496     if (new_thread_id == -1)
   500     if (new_thread_id != -1)
   501         debug(
"gwlib.gwthread", 0, 
"Started thread %ld (%s)", new_thread_id, 
name);
   503         debug(
"gwlib.gwthread", 0, 
"Failed to start thread (%s)", 
name);
   505     return new_thread_id;
   511     sigset_t old_signal_set;
   544     pthread_cond_t exit_cond;
   560     ret = pthread_cond_init(&exit_cond, NULL);
   562         warning(ret, 
"gwthread_join: cannot create condition variable.");
   574     pthread_cleanup_push((
void(*)(
void*))pthread_mutex_unlock, &
threadtable_lock);
   576     pthread_cleanup_pop(0);
   580         warning(ret, 
"gwthread_join: error in pthread_cond_wait");
   582     pthread_cond_destroy(&exit_cond);
   610     pthread_cond_t exit_cond;
   614     ret = pthread_cond_init(&exit_cond, NULL);
   616         warning(ret, 
"gwthread_join_every: cannot create condition variable.");
   632         debug(
"gwlib.gwthread", 0,
   633               "Waiting for %ld (%s) to terminate",
   638         pthread_cleanup_push((
void(*)(
void*))pthread_mutex_unlock, &
threadtable_lock);
   640         pthread_cleanup_pop(0);
   642             warning(ret, 
"gwthread_join_all: error in pthread_cond_wait");
   646     pthread_cond_destroy(&exit_cond);
   668         return (
long) getpid();
   723     milliseconds = timeout * 1000;
   724     if (milliseconds < 0)
   730             error(errno, 
"gwthread_pollfd: error in poll");
   752     pollfds = gw_malloc((numfds + 1) * 
sizeof(*pollfds));
   756     memcpy(pollfds + 1, fds, numfds * 
sizeof(*pollfds));
   758     milliseconds = timeout * 1000;
   759     if (milliseconds < 0)
   762     ret = 
poll(pollfds, numfds + 1, milliseconds);
   765             error(errno, 
"gwthread_poll: error in poll");
   769     if (pollfds[0].revents)
   773     memcpy(fds, pollfds + 1, numfds * 
sizeof(*pollfds));
   792     milliseconds = seconds * 1000;
   793     if (milliseconds < 0)
   798         if (errno != EINTR && errno != EAGAIN) {
   799             warning(errno, 
"gwthread_sleep: error in poll");
   818     FD_ZERO(&fd_set_recv);
   819     FD_SET(fd, &fd_set_recv);
   822         ret = select(fd + 1, &fd_set_recv, NULL, NULL, NULL);
   824         struct timeval timeout;
   825         timeout.tv_sec = dseconds;
   826         timeout.tv_usec = (dseconds - timeout.tv_sec) * 1000000;
   828         ret = select(fd + 1, &fd_set_recv, NULL, NULL, &timeout);
   832         if (errno != EINTR && errno != EAGAIN) {
   833             warning(errno, 
"gwthread_sleep_micro: error in select()");
   837     if (FD_ISSET(fd, &fd_set_recv)) {
   856         debug(
"gwlib.gwthread", 0, 
"Thread %ld (%s) canceled.",
   864 #ifndef BROKEN_PTHREADS   883     if (pthread_sigmask(SIG_BLOCK, NULL, &signal_set) != 0) {
   884         warning(0, 
"gwthread_dumpsigmask: Couldn't get signal mask.");
   890     for (signum = 1; signum <= 32; signum++) {
   891          if (!sigismember(&signal_set, signum)) {
   893              "gwthread_dumpsigmask: Signal Number %d will be caught.", 
   902 #if defined(DARWIN_OLD)   903 static int pthread_sigmask()
 
void error(int err, const char *fmt,...)
 
void gwthread_join_all(void)
 
int socket_set_blocking(int fd, int blocking)
 
static struct threadinfo * threadtable[THREADTABLE_SIZE]
 
static void new_thread_cleanup(void *arg)
 
gw_assert(wtls_machine->packet_to_send !=NULL)
 
void gwlist_append(List *list, void *item)
 
void gwthread_join(long thread)
 
#define poll(fdarray, numfds, timeout)
 
void gwthread_sleep_micro(double dseconds)
 
int gwthread_shouldhandlesignal(int signal)
 
void gwthread_self_ids(long *tid, long *pid)
 
int gwthread_poll(struct pollfd *fds, long numfds, double timeout)
 
void gwthread_join_every(gwthread_func_t *func)
 
static long next_threadnumber
 
void gwthread_func_t(void *arg)
 
static long active_threads
 
long gwthread_self_pid(void)
 
void * gwlist_extract_first(List *list)
 
static struct threadinfo * getthreadinfo(void)
 
static void delete_threadinfo(void)
 
void gwthread_shutdown(void)
 
void warning(int err, const char *fmt,...)
 
static void alert_joiners(void)
 
void gwthread_sleep(double seconds)
 
static long fill_threadinfo(pthread_t id, const char *name, gwthread_func_t *func, struct threadinfo *ti)
 
static struct threadinfo mainthread
 
int gwthread_pollfd(int fd, int events, double timeout)
 
static pthread_mutex_t threadtable_lock
 
void debug(const char *place, int err, const char *fmt,...)
 
void gwthread_wakeup(long thread)
 
static pthread_key_t tsd_key
 
long gwthread_create_real(gwthread_func_t *func, const char *name, void *arg)
 
int gwthread_cancel(long thread)
 
static long spawn_thread(gwthread_func_t *func, const char *name, void *arg)
 
static void restore_user_signals(sigset_t *old_set)
 
void gwthread_wakeup_all(void)
 
static void flushpipe(int fd)
 
static int block_user_signals(sigset_t *old_set_storage)
 
static void * new_thread(void *arg)
 
int gwthread_dumpsigmask(void)
 
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)