Kannel: Open Source WAP and SMS gateway  $Revision: 5037 $
gwthread.h File Reference
#include "gw-config.h"

Go to the source code of this file.

Macros

#define MAIN_THREAD_ID   0
 
#define gwthread_create(func, arg)   (gwthread_create_real(func, __FILE__ ":" #func, arg))
 

Typedefs

typedef void gwthread_func_t(void *arg)
 

Functions

void gwthread_init (void)
 
void gwthread_shutdown (void)
 
long gwthread_create_real (gwthread_func_t *func, const char *funcname, void *arg)
 
void gwthread_join (long thread)
 
void gwthread_join_every (gwthread_func_t *func)
 
void gwthread_join_all (void)
 
long gwthread_self (void)
 
long gwthread_self_pid (void)
 
void gwthread_self_ids (long *tid, long *pid)
 
void gwthread_wakeup (long thread)
 
void gwthread_wakeup_all (void)
 
int gwthread_pollfd (int fd, int events, double timeout)
 
int gwthread_poll (struct pollfd *fds, long numfds, double timeout)
 
void gwthread_sleep (double seconds)
 
void gwthread_sleep_micro (double dseconds)
 
int gwthread_cancel (long thread)
 
int gwthread_shouldhandlesignal (int signal)
 
int gwthread_dumpsigmask (void)
 

Macro Definition Documentation

◆ gwthread_create

◆ MAIN_THREAD_ID

#define MAIN_THREAD_ID   0

Typedef Documentation

◆ gwthread_func_t

typedef void gwthread_func_t(void *arg)

Definition at line 79 of file gwthread.h.

Function Documentation

◆ gwthread_cancel()

int gwthread_cancel ( long  thread)

Definition at line 843 of file gwthread-pthread.c.

References debug(), gw_assert(), lock(), threadinfo::name, threadinfo::number, threadinfo::self, THREAD, and unlock().

Referenced by main().

844 {
845  struct threadinfo *threadinfo;
846  int ret;
847 
848  gw_assert(thread >= 0);
849 
850  lock();
851  threadinfo = THREAD(thread);
852  if (threadinfo == NULL || threadinfo->number != thread) {
853  ret = -1;
854  } else {
855  ret = pthread_cancel(threadinfo->self);
856  debug("gwlib.gwthread", 0, "Thread %ld (%s) canceled.",
857  threadinfo->number, threadinfo->name);
858  }
859  unlock();
860  return ret;
861 }
gw_assert(wtls_machine->packet_to_send !=NULL)
const char * name
static void unlock(void)
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
#define THREAD(t)
static void lock(void)
pthread_t self

◆ gwthread_create_real()

long gwthread_create_real ( gwthread_func_t func,
const char *  funcname,
void *  arg 
)

Definition at line 508 of file gwthread-pthread.c.

References block_user_signals(), gwthread_self(), MAIN_THREAD_ID, restore_user_signals(), and spawn_thread().

509 {
510  int sigtrick = 0;
511  sigset_t old_signal_set;
512  long thread_id;
513 
514  /*
515  * We want to make sure that only the main thread handles signals,
516  * so that each signal is handled exactly once. To do this, we
517  * make sure that each new thread has all the signals that we
518  * handle blocked. To avoid race conditions, we block them in
519  * the spawning thread first, then create the new thread (which
520  * inherits the settings), and then restore the old settings in
521  * the spawning thread. This means that there is a brief period
522  * when no signals will be processed, but during that time they
523  * should be queued by the operating system.
524  */
525  if (gwthread_self() == MAIN_THREAD_ID)
526  sigtrick = block_user_signals(&old_signal_set) == 0;
527 
528  thread_id = spawn_thread(func, name, arg);
529 
530  /*
531  * Restore the old signal mask. The new thread will have
532  * inherited the resticted one, but the main thread needs
533  * the old one back.
534  */
535  if (sigtrick)
536  restore_user_signals(&old_signal_set);
537 
538  return thread_id;
539 }
long gwthread_self(void)
gwthread_func_t * func
char * name
Definition: smsc_cimd2.c:212
#define MAIN_THREAD_ID
Definition: gwthread.h:77
static long spawn_thread(gwthread_func_t *func, const char *name, void *arg)
static void restore_user_signals(sigset_t *old_set)
static int block_user_signals(sigset_t *old_set_storage)

◆ gwthread_dumpsigmask()

int gwthread_dumpsigmask ( void  )

Definition at line 878 of file gwthread-pthread.c.

References debug(), and warning().

878  {
879  sigset_t signal_set;
880  int signum;
881 
882  /* Grab the signal set data from our thread */
883  if (pthread_sigmask(SIG_BLOCK, NULL, &signal_set) != 0) {
884  warning(0, "gwthread_dumpsigmask: Couldn't get signal mask.");
885  return -1;
886  }
887 
888  /* For each signal normally defined (there are usually only 32),
889  * print a message if we don't block it. */
890  for (signum = 1; signum <= 32; signum++) {
891  if (!sigismember(&signal_set, signum)) {
892  debug("gwlib", 0,
893  "gwthread_dumpsigmask: Signal Number %d will be caught.",
894  signum);
895  }
896  }
897  return 0;
898 }
void warning(int err, const char *fmt,...)
Definition: log.c:660
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726

◆ gwthread_init()

void gwthread_init ( void  )

Definition at line 267 of file gwthread-pthread.c.

References active_threads, fill_threadinfo(), mainthread, panic, threadtable_lock, THREADTABLE_SIZE, and tsd_key.

Referenced by gwlib_init().

268 {
269  int ret;
270  int i;
271 
272  pthread_mutex_init(&threadtable_lock, NULL);
273 
274  ret = pthread_key_create(&tsd_key, NULL);
275  if (ret != 0) {
276  panic(ret, "gwthread-pthread: pthread_key_create failed");
277  }
278 
279  for (i = 0; i < THREADTABLE_SIZE; i++) {
280  threadtable[i] = NULL;
281  }
282  active_threads = 0;
283 
284  /* create main thread info */
285  if (fill_threadinfo(pthread_self(), "main", NULL, &mainthread) == -1)
286  panic(0, "gwthread-pthread: unable to fill main threadinfo.");
287 
288  ret = pthread_setspecific(tsd_key, &mainthread);
289  if (ret != 0)
290  panic(ret, "gwthread-pthread: pthread_setspecific failed");
291 }
#define THREADTABLE_SIZE
static struct threadinfo * threadtable[THREADTABLE_SIZE]
static long active_threads
static long fill_threadinfo(pthread_t id, const char *name, gwthread_func_t *func, struct threadinfo *ti)
static struct threadinfo mainthread
static pthread_mutex_t threadtable_lock
#define panic
Definition: log.h:87
static pthread_key_t tsd_key

◆ gwthread_join()

void gwthread_join ( long  thread)

Definition at line 541 of file gwthread-pthread.c.

References gw_assert(), gwlist_append(), gwlist_create, threadinfo::joiners, lock(), threadinfo::number, THREAD, threadtable_lock, unlock(), and warning().

Referenced by cimd2_shutdown_cb(), emi2_sender(), fdset_destroy(), gw_timerset_destroy(), gwthread_join_all(), heartbeat_stop(), httpd_emu_destroy(), httpsmsc_receiver(), httpsmsc_sender(), io_thread(), main(), oisd_shutdown_cb(), receive_smpp_thread(), run_smppbox(), run_smsbox(), run_sqlbox(), run_wapbox(), shutdown_cb(), smpp_emu(), smpp_emu_reader(), smsboxc_run(), smsc_cimd2_create(), smsc_emi2_create(), smsc_emu_destroy(), smsc_oisd_create(), smsc_smpp_create(), soap_server_stop(), soap_shutdown_cb(), store_file_shutdown(), timers_shutdown(), udp_sender(), and wrapper_sender().

542 {
543  struct threadinfo *threadinfo;
544  pthread_cond_t exit_cond;
545  int ret;
546 
547  gw_assert(thread >= 0);
548 
549  lock();
550  threadinfo = THREAD(thread);
551  if (threadinfo == NULL || threadinfo->number != thread) {
552  /* The other thread has already exited */
553  unlock();
554  return;
555  }
556 
557  /* Register our desire to be alerted when that thread exits,
558  * and wait for it. */
559 
560  ret = pthread_cond_init(&exit_cond, NULL);
561  if (ret != 0) {
562  warning(ret, "gwthread_join: cannot create condition variable.");
563  unlock();
564  return;
565  }
566 
567  if (!threadinfo->joiners)
568  threadinfo->joiners = gwlist_create();
569  gwlist_append(threadinfo->joiners, &exit_cond);
570 
571  /* The wait immediately releases the lock, and reacquires it
572  * when the condition is satisfied. So don't worry, we're not
573  * blocking while keeping the table locked. */
574  pthread_cleanup_push((void(*)(void*))pthread_mutex_unlock, &threadtable_lock);
575  ret = pthread_cond_wait(&exit_cond, &threadtable_lock);
576  pthread_cleanup_pop(0);
577  unlock();
578 
579  if (ret != 0)
580  warning(ret, "gwthread_join: error in pthread_cond_wait");
581 
582  pthread_cond_destroy(&exit_cond);
583 }
gw_assert(wtls_machine->packet_to_send !=NULL)
void gwlist_append(List *list, void *item)
Definition: list.c:179
void warning(int err, const char *fmt,...)
Definition: log.c:660
static void unlock(void)
static pthread_mutex_t threadtable_lock
#define THREAD(t)
#define gwlist_create()
Definition: list.h:136
static void lock(void)

◆ gwthread_join_all()

void gwthread_join_all ( void  )

Definition at line 585 of file gwthread-pthread.c.

References gwthread_join(), gwthread_self(), THREAD, and THREADTABLE_SIZE.

Referenced by main().

586 {
587  long i;
588  long our_thread = gwthread_self();
589 
590  for (i = 0; i < THREADTABLE_SIZE; ++i) {
591  if (THREAD(our_thread) != THREAD(i))
592  gwthread_join(i);
593  }
594 }
#define THREADTABLE_SIZE
long gwthread_self(void)
void gwthread_join(long thread)
#define THREAD(t)

◆ gwthread_join_every()

void gwthread_join_every ( gwthread_func_t func)

Definition at line 607 of file gwthread-pthread.c.

References debug(), threadinfo::func, gwlist_append(), gwlist_create, threadinfo::joiners, lock(), threadinfo::name, threadinfo::number, THREAD, threadtable_lock, THREADTABLE_SIZE, unlock(), and warning().

Referenced by client_shutdown(), http_close_all_ports(), httpadmin_stop(), main(), main_for_producer_and_consumer(), radius_acct_shutdown(), server_shutdown(), wap_appl_shutdown(), wap_push_ota_shutdown(), wap_push_ppg_shutdown(), wsp_push_client_shutdown(), wsp_session_shutdown(), wsp_unit_shutdown(), wtp_initiator_shutdown(), and wtp_resp_shutdown().

608 {
609  struct threadinfo *ti;
610  pthread_cond_t exit_cond;
611  int ret;
612  long i;
613 
614  ret = pthread_cond_init(&exit_cond, NULL);
615  if (ret != 0) {
616  warning(ret, "gwthread_join_every: cannot create condition variable.");
617  unlock();
618  return;
619  }
620 
621  /*
622  * FIXME: To be really safe, this function should keep looping
623  * over the table until it does a complete run without having
624  * to call pthread_cond_wait. Otherwise, new threads could
625  * start while we wait, and we'll miss them.
626  */
627  lock();
628  for (i = 0; i < THREADTABLE_SIZE; ++i) {
629  ti = THREAD(i);
630  if (ti == NULL || ti->func != func)
631  continue;
632  debug("gwlib.gwthread", 0,
633  "Waiting for %ld (%s) to terminate",
634  ti->number, ti->name);
635  if (!ti->joiners)
636  ti->joiners = gwlist_create();
637  gwlist_append(ti->joiners, &exit_cond);
638  pthread_cleanup_push((void(*)(void*))pthread_mutex_unlock, &threadtable_lock);
639  ret = pthread_cond_wait(&exit_cond, &threadtable_lock);
640  pthread_cleanup_pop(0);
641  if (ret != 0)
642  warning(ret, "gwthread_join_all: error in pthread_cond_wait");
643  }
644  unlock();
645 
646  pthread_cond_destroy(&exit_cond);
647 }
#define THREADTABLE_SIZE
void gwlist_append(List *list, void *item)
Definition: list.c:179
const char * name
gwthread_func_t * func
void warning(int err, const char *fmt,...)
Definition: log.c:660
static void unlock(void)
static pthread_mutex_t threadtable_lock
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
#define THREAD(t)
#define gwlist_create()
Definition: list.h:136
static void lock(void)

◆ gwthread_poll()

int gwthread_poll ( struct pollfd fds,
long  numfds,
double  timeout 
)

Definition at line 740 of file gwthread-pthread.c.

References error(), pollfd::events, pollfd::fd, flushpipe(), getthreadinfo(), poll, POLL_NOTIMEOUT, POLLIN, pollfd::revents, and threadinfo::wakefd_recv.

Referenced by poller(), and server_thread().

741 {
742  struct pollfd *pollfds;
743  struct threadinfo *threadinfo;
744  int milliseconds;
745  int ret;
746 
747  threadinfo = getthreadinfo();
748 
749  /* Create a new pollfd array with an extra element for the
750  * thread wakeup fd. */
751 
752  pollfds = gw_malloc((numfds + 1) * sizeof(*pollfds));
753  pollfds[0].fd = threadinfo->wakefd_recv;
754  pollfds[0].events = POLLIN;
755  pollfds[0].revents = 0;
756  memcpy(pollfds + 1, fds, numfds * sizeof(*pollfds));
757 
758  milliseconds = timeout * 1000;
759  if (milliseconds < 0)
760  milliseconds = POLL_NOTIMEOUT;
761 
762  ret = poll(pollfds, numfds + 1, milliseconds);
763  if (ret < 0) {
764  if (errno != EINTR)
765  error(errno, "gwthread_poll: error in poll");
766  gw_free(pollfds);
767  return -1;
768  }
769  if (pollfds[0].revents)
770  flushpipe(pollfds[0].fd);
771 
772  /* Copy the results back to the caller */
773  memcpy(fds, pollfds + 1, numfds * sizeof(*pollfds));
774  gw_free(pollfds);
775 
776  return ret;
777 }
void error(int err, const char *fmt,...)
Definition: log.c:648
#define poll(fdarray, numfds, timeout)
Definition: gwpoll.h:104
#define POLL_NOTIMEOUT
Definition: gwpoll.h:100
short events
Definition: gwpoll.h:86
#define POLLIN
Definition: gwpoll.h:91
static struct threadinfo * getthreadinfo(void)
Definition: gwpoll.h:84
int fd
Definition: gwpoll.h:85
short revents
Definition: gwpoll.h:87
static void flushpipe(int fd)

◆ gwthread_pollfd()

int gwthread_pollfd ( int  fd,
int  events,
double  timeout 
)

Definition at line 706 of file gwthread-pthread.c.

References error(), pollfd::events, pollfd::fd, flushpipe(), getthreadinfo(), poll, POLL_NOTIMEOUT, POLLIN, pollfd::revents, and threadinfo::wakefd_recv.

Referenced by accept_thread(), cgw_listener(), cgw_wait_command(), conn_flush(), conn_wait(), emi2_listener(), fake_listener(), gw_accept(), and wait_for_connections().

707 {
708  struct pollfd pollfd[2];
709  struct threadinfo *threadinfo;
710  int milliseconds;
711  int ret;
712 
713  threadinfo = getthreadinfo();
714 
715  pollfd[0].fd = threadinfo->wakefd_recv;
716  pollfd[0].events = POLLIN;
717  pollfd[0].revents = 0;
718 
719  pollfd[1].fd = fd;
720  pollfd[1].events = events;
721  pollfd[1].revents = 0;
722 
723  milliseconds = timeout * 1000;
724  if (milliseconds < 0)
725  milliseconds = POLL_NOTIMEOUT;
726 
727  ret = poll(pollfd, 2, milliseconds);
728  if (ret < 0) {
729  if (errno != EINTR)
730  error(errno, "gwthread_pollfd: error in poll");
731  return -1;
732  }
733 
734  if (pollfd[0].revents)
735  flushpipe(pollfd[0].fd);
736 
737  return pollfd[1].revents;
738 }
void error(int err, const char *fmt,...)
Definition: log.c:648
#define poll(fdarray, numfds, timeout)
Definition: gwpoll.h:104
#define POLL_NOTIMEOUT
Definition: gwpoll.h:100
short events
Definition: gwpoll.h:86
#define POLLIN
Definition: gwpoll.h:91
static struct threadinfo * getthreadinfo(void)
Definition: gwpoll.h:84
int fd
Definition: gwpoll.h:85
short revents
Definition: gwpoll.h:87
static void flushpipe(int fd)

◆ gwthread_self()

long gwthread_self ( void  )

Definition at line 650 of file gwthread-pthread.c.

651 {
652  struct threadinfo *threadinfo;
653  threadinfo = pthread_getspecific(tsd_key);
654  if (threadinfo)
655  return threadinfo->number;
656  else
657  return -1;
658 }
static pthread_key_t tsd_key

◆ gwthread_self_ids()

void gwthread_self_ids ( long *  tid,
long *  pid 
)

Definition at line 671 of file gwthread-pthread.c.

References threadinfo::number, threadinfo::pid, and tsd_key.

Referenced by format().

672 {
673  struct threadinfo *threadinfo;
674  threadinfo = pthread_getspecific(tsd_key);
675  if (threadinfo) {
676  *tid = threadinfo->number;
677  *pid = (threadinfo->pid != -1) ? threadinfo->pid : getpid();
678  } else {
679  *tid = -1;
680  *pid = getpid();
681  }
682 }
static pthread_key_t tsd_key

◆ gwthread_self_pid()

long gwthread_self_pid ( void  )

Definition at line 661 of file gwthread-pthread.c.

References threadinfo::pid, and tsd_key.

662 {
663  struct threadinfo *threadinfo;
664  threadinfo = pthread_getspecific(tsd_key);
665  if (threadinfo && threadinfo->pid != -1)
666  return (long) threadinfo->pid;
667  else
668  return (long) getpid();
669 }
static pthread_key_t tsd_key

◆ gwthread_shouldhandlesignal()

int gwthread_shouldhandlesignal ( int  signal)

Definition at line 867 of file gwthread-pthread.c.

References gwthread_self(), gwthread_shouldhandlesignal(), and MAIN_THREAD_ID.

Referenced by gwthread_shouldhandlesignal(), and signal_handler().

867  {
868  return 1;
869 }

◆ gwthread_shutdown()

void gwthread_shutdown ( void  )

Definition at line 296 of file gwthread-pthread.c.

References debug(), gw_assert(), lock(), threadinfo::name, threadinfo::number, running, threadtable_lock, THREADTABLE_SIZE, unlock(), and warning().

Referenced by gwlib_shutdown().

297 {
298  int ret;
299  int running;
300  int i;
301 
302  /* Main thread must not have disappeared */
303  gw_assert(threadtable[0] != NULL);
304  lock();
305 
306  running = 0;
307  /* Start i at 1 to skip the main thread, which is supposed to be
308  * still running. */
309  for (i = 1; i < THREADTABLE_SIZE; i++) {
310  if (threadtable[i] != NULL) {
311  debug("gwlib", 0, "Thread %ld (%s) still running",
312  threadtable[i]->number,
313  threadtable[i]->name);
314  running++;
315  }
316  }
317  unlock();
318 
319  /* We can't do a full cleanup this way */
320  if (running)
321  return;
322 
323  ret = pthread_mutex_destroy(&threadtable_lock);
324  if (ret != 0) {
325  warning(ret, "cannot destroy threadtable lock");
326  }
327 
328  /* We can't delete the tsd_key here, because gwthread_self()
329  * still needs it to access the main thread's info. */
330 }
#define THREADTABLE_SIZE
int number
Definition: smsc_cimd2.c:213
static struct threadinfo * threadtable[THREADTABLE_SIZE]
gw_assert(wtls_machine->packet_to_send !=NULL)
Definition: shared.h:81
char * name
Definition: smsc_cimd2.c:212
void warning(int err, const char *fmt,...)
Definition: log.c:660
static void unlock(void)
static pthread_mutex_t threadtable_lock
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
static void lock(void)

◆ gwthread_sleep()

void gwthread_sleep ( double  seconds)

Definition at line 780 of file gwthread-pthread.c.

References pollfd::events, pollfd::fd, flushpipe(), getthreadinfo(), poll, POLL_NOTIMEOUT, POLLIN, threadinfo::wakefd_recv, and warning().

Referenced by at2_detect_modem_type(), at2_device_thread(), at2_init_device(), at2_login_device(), at2_send_one_message(), at2_write(), at2_write_ctrlz(), at2_write_line(), bb_smscconn_receive_internal(), cgw_open_send_connection(), client_thread(), emi2_do_send(), emi2_wait(), heartbeat_thread(), httpd_check_authorization(), httpsmsc_send_cb(), httpsmsc_sender(), io_thread(), main(), main_connection_loop(), open_send_connection(), parachute_start(), poller(), port_remove(), push_thread(), reconnect(), restart_box(), send_message(), send_messages(), send_smpp_thread(), server_thread(), smasi_thread(), smpp_to_bearerbox(), sms_router(), sms_to_smsboxes(), smsbox_thread(), smsboxc_run(), smsc2_graceful_restart(), soap_listener(), soap_server(), sql_list(), sql_single(), store_dumper(), thread1(), thread2(), wait_for_connections(), wapboxc_run(), watch_timers(), and wrapper_receiver().

781 {
782  struct pollfd pollfd;
783  struct threadinfo *threadinfo;
784  int milliseconds;
785  int ret;
786 
787  threadinfo = getthreadinfo();
788 
789  pollfd.fd = threadinfo->wakefd_recv;
790  pollfd.events = POLLIN;
791 
792  milliseconds = seconds * 1000;
793  if (milliseconds < 0)
794  milliseconds = POLL_NOTIMEOUT;
795 
796  ret = poll(&pollfd, 1, milliseconds);
797  if (ret < 0) {
798  if (errno != EINTR && errno != EAGAIN) {
799  warning(errno, "gwthread_sleep: error in poll");
800  }
801  }
802  if (ret == 1) {
804  }
805 }
#define poll(fdarray, numfds, timeout)
Definition: gwpoll.h:104
#define POLL_NOTIMEOUT
Definition: gwpoll.h:100
short events
Definition: gwpoll.h:86
#define POLLIN
Definition: gwpoll.h:91
static struct threadinfo * getthreadinfo(void)
void warning(int err, const char *fmt,...)
Definition: log.c:660
Definition: gwpoll.h:84
int fd
Definition: gwpoll.h:85
static void flushpipe(int fd)

◆ gwthread_sleep_micro()

void gwthread_sleep_micro ( double  dseconds)

Definition at line 808 of file gwthread-pthread.c.

References flushpipe(), getthreadinfo(), threadinfo::wakefd_recv, and warning().

809 {
810  fd_set fd_set_recv;
811  struct threadinfo *threadinfo;
812  int fd;
813  int ret;
814 
815  threadinfo = getthreadinfo();
816  fd = threadinfo->wakefd_recv;
817 
818  FD_ZERO(&fd_set_recv);
819  FD_SET(fd, &fd_set_recv);
820 
821  if (dseconds < 0) {
822  ret = select(fd + 1, &fd_set_recv, NULL, NULL, NULL);
823  } else {
824  struct timeval timeout;
825  timeout.tv_sec = dseconds;
826  timeout.tv_usec = (dseconds - timeout.tv_sec) * 1000000;
827 
828  ret = select(fd + 1, &fd_set_recv, NULL, NULL, &timeout);
829  }
830 
831  if (ret < 0) {
832  if (errno != EINTR && errno != EAGAIN) {
833  warning(errno, "gwthread_sleep_micro: error in select()");
834  }
835  }
836 
837  if (FD_ISSET(fd, &fd_set_recv)) {
838  flushpipe(fd);
839  }
840 }
static struct threadinfo * getthreadinfo(void)
void warning(int err, const char *fmt,...)
Definition: log.c:660
static void flushpipe(int fd)

◆ gwthread_wakeup()

void gwthread_wakeup ( long  thread)

Definition at line 684 of file gwthread-pthread.c.

References gw_assert(), lock(), threadinfo::number, THREAD, unlock(), and threadinfo::wakefd_send.

Referenced by add_msg_cb(), at2_add_msg_cb(), at2_shutdown_cb(), at2_start_cb(), bb_smscconn_connected(), boxc_receiver(), cgw_add_msg_cb(), cgw_listener(), cgw_shutdown_cb(), cgw_start_cb(), cimd2_add_msg_cb(), cimd2_shutdown_cb(), cimd2_start_cb(), client_destroy(), emi2_idleprocessing(), emi2_listener(), emi2_sender(), gw_timer_elapsed_start(), gw_timer_start(), gw_timerset_destroy(), gwthread_wakeup_all(), gwtimer_start(), heartbeat_stop(), http_close_all_ports(), http_close_port(), http_open_port_if(), httpd_shutdown(), httpsmsc_receiver(), httpsmsc_sender(), httpsmsc_shutdown(), io_thread(), main(), oisd_add_msg_cb(), oisd_shutdown_cb(), oisd_start_cb(), run_smsbox(), send_msg_cb(), server_shutdown(), shutdown_cb(), smpp_emu(), sms_router(), smsboxc_run(), smsc2_graceful_restart(), smsc2_restart_smsc(), smsc2_resume(), smsc2_shutdown(), smsc_cimd2_create(), smsc_emi2_create(), smsc_emu_destroy(), smsc_oisd_create(), smsc_smpp_create(), soap_add_msg_cb(), soap_server_stop(), soap_shutdown_cb(), start_cb(), store_file_shutdown(), submit_action(), submit_action_nosync(), timers_shutdown(), udp_receiver(), wapboxc_run(), wrapper_sender(), and wrapper_shutdown().

685 {
686  unsigned char c = 0;
687  struct threadinfo *threadinfo;
688  int fd;
689 
690  gw_assert(thread >= 0);
691 
692  lock();
693 
694  threadinfo = THREAD(thread);
695  if (threadinfo == NULL || threadinfo->number != thread) {
696  unlock();
697  return;
698  }
699 
700  fd = threadinfo->wakefd_send;
701  unlock();
702 
703  write(fd, &c, 1);
704 }
gw_assert(wtls_machine->packet_to_send !=NULL)
static void unlock(void)
#define THREAD(t)
static void lock(void)

◆ gwthread_wakeup_all()

void gwthread_wakeup_all ( void  )

Definition at line 596 of file gwthread-pthread.c.

References gwthread_self(), gwthread_wakeup(), THREAD, and THREADTABLE_SIZE.

Referenced by httpd_restart(), main(), and quit().

597 {
598  long i;
599  long our_thread = gwthread_self();
600 
601  for (i = 0; i < THREADTABLE_SIZE; ++i) {
602  if (THREAD(our_thread) != THREAD(i))
603  gwthread_wakeup(i);
604  }
605 }
#define THREADTABLE_SIZE
long gwthread_self(void)
#define THREAD(t)
void gwthread_wakeup(long thread)
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.