00001 /* 00002 Queued-signals example using threads 00003 AUP2, Sec. 9.05.5 00004 00005 Copyright 2003 by Marc J. Rochkind. All rights reserved. 00006 May be copied only for purposes and under conditions described 00007 on the Web page www.basepath.com/aup/copyright.htm. 00008 00009 The Example Files are provided "as is," without any warranty; 00010 without even the implied warranty of merchantability or fitness 00011 for a particular purpose. The author and his publisher are not 00012 responsible for any damages, direct or incidental, resulting 00013 from the use or non-use of these Example Files. 00014 00015 The Example Files may contain defects, and some contain deliberate 00016 coding mistakes that were included for educational reasons. 00017 You are responsible for determining if and how the Example Files 00018 are to be used. 00019 00020 */ 00021 /* 00022 Won't work on some imperfect implementations of POSIX threads, such as 00023 some versions of Linux threads, because signals ququed for a process 00024 are not properly distributed to a thread. 00025 */ 00026 #include "defs.h" 00027 00028 #if _POSIX_REALTIME_SIGNALS > 0 00029 00030 #include <pthread.h> 00031 00032 /*[top]*/ 00033 #define MYSIG_COUNT SIGRTMIN 00034 #define MYSIG_STOP SIGRTMIN + 1 00035 /*[sig_thread]*/ 00036 static void *sig_thread(void *arg) 00037 { 00038 int signum; 00039 siginfo_t info; 00040 00041 do { 00042 signum = sigwaitinfo((sigset_t *)arg, &info); 00043 if (signum == MYSIG_COUNT) 00044 printf("Got MYSIG_COUNT; value: %s\n", 00045 (char *)info.si_value.sival_ptr); 00046 else if (signum == MYSIG_STOP) { 00047 printf("Got MYSIG_STOP; terminating thread\n"); 00048 return (void *)true; 00049 } 00050 else 00051 printf("Got %d\n", signum); 00052 } while (signum != -1 || errno == EINTR); 00053 EC_FAIL 00054 00055 EC_CLEANUP_BGN 00056 EC_FLUSH("sig_thread") 00057 return (void *)false; 00058 EC_CLEANUP_END 00059 } 00060 /*[handler]*/ 00061 static void dummy_handler(int signum, siginfo_t *info, void *context) 00062 { 00063 } 00064 /*[main]*/ 00065 int main(void) 00066 { 00067 sigset_t set; 00068 struct sigaction act; 00069 union sigval value; 00070 pthread_t tid; 00071 00072 #ifdef LINUX 00073 printf("Warning: May hang -- see comment at the top of c9/thrq.c\n"); 00074 #endif 00075 ec_neg1( sigemptyset(&set) ) 00076 ec_neg1( sigaddset(&set, MYSIG_COUNT) ) 00077 ec_neg1( sigaddset(&set, MYSIG_STOP) ) 00078 ec_rv( pthread_sigmask(SIG_SETMASK, &set, NULL) ) 00079 memset(&act, 0, sizeof(act)); 00080 act.sa_flags = SA_SIGINFO; 00081 act.sa_sigaction = dummy_handler; 00082 ec_neg1( sigaction(MYSIG_COUNT, &act, NULL) ) 00083 ec_neg1( sigaction(MYSIG_STOP, &act, NULL) ) 00084 value.sival_ptr = "One"; 00085 ec_neg1( sigqueue(getpid(), MYSIG_COUNT, value) ) 00086 value.sival_ptr = "Two"; 00087 ec_neg1( sigqueue(getpid(), MYSIG_COUNT, value) ) 00088 value.sival_ptr = "Three"; 00089 ec_neg1( sigqueue(getpid(), MYSIG_COUNT, value) ) 00090 value.sival_ptr = NULL; 00091 ec_neg1( sigqueue(getpid(), MYSIG_STOP, value) ) 00092 ec_rv( pthread_create(&tid, NULL, sig_thread, &set) ) 00093 ec_rv( pthread_join(tid, NULL) ) 00094 exit(EXIT_SUCCESS); 00095 00096 EC_CLEANUP_BGN 00097 exit(EXIT_FAILURE); 00098 EC_CLEANUP_END 00099 } 00100 /*[]*/ 00101 00102 #else /* _POSIX_REALTIME_SIGNALS */ 00103 00104 int main(void) 00105 { 00106 printf("Not supported.\n"); 00107 exit(1); 00108 } 00109 00110 #endif /* _POSIX_REALTIME_SIGNALS */