00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <config.h>
00035
00036 #include <errno.h>
00037 #include <stddef.h>
00038 #include <signal.h>
00039 #include "lwp.h"
00040 #include "lwpint.h"
00041
00042
00043
00044
00045
00046 static sigset_t LwpSigCatched;
00047
00048
00049
00050
00051 static sig_atomic_t LwpSigCheck;
00052
00053
00054 static struct lwpProc *LwpSigWaiter;
00055
00056 static void lwpCatchAwaitedSig(int);
00057
00058
00059
00060
00061 void
00062 lwpInitSigWait(sigset_t *set)
00063 {
00064 struct sigaction act;
00065 int i;
00066
00067 sigemptyset(&LwpSigCatched);
00068
00069 act.sa_flags = 0;
00070 act.sa_mask = *set;
00071 sigemptyset(&act.sa_mask);
00072 act.sa_handler = lwpCatchAwaitedSig;
00073 for (i = 0; i < NSIG; i++) {
00074 if (sigismember(set, i))
00075 sigaction(i, &act, NULL);
00076 }
00077 }
00078
00079 static void
00080 lwpCatchAwaitedSig(int sig)
00081 {
00082 sigaddset(&LwpSigCatched, sig);
00083 LwpSigCheck = 1;
00084 }
00085
00086
00087
00088
00089
00090
00091
00092 static int
00093 lwpGetSig(sigset_t *set)
00094 {
00095 sigset_t save;
00096 int i;
00097
00098 sigprocmask(SIG_BLOCK, set, &save);
00099 for (i = NSIG - 1; i > 0; i--) {
00100 if (sigismember(set, i) && sigismember(&LwpSigCatched, i)) {
00101 lwpStatus(LwpCurrent, "Got awaited signal %d", i);
00102 sigdelset(&LwpSigCatched, i);
00103 break;
00104 }
00105 }
00106 sigprocmask(SIG_SETMASK, &save, NULL);
00107 return i;
00108 }
00109
00110
00111
00112
00113
00114
00115
00116 int
00117 lwpSigWait(sigset_t *set, int *sig)
00118 {
00119 int res;
00120
00121 if (CANT_HAPPEN(LwpSigWaiter))
00122 return EBUSY;
00123 for (;;) {
00124 LwpSigCheck = 0;
00125 res = lwpGetSig(set);
00126 if (res > 0)
00127 break;
00128 lwpStatus(LwpCurrent, "Waiting for signals");
00129 LwpSigWaiter = LwpCurrent;
00130 lwpReschedule();
00131 }
00132 *sig = res;
00133 return 0;
00134 }
00135
00136
00137
00138
00139
00140 void
00141 lwpSigWakeup(void)
00142 {
00143 if (LwpSigWaiter && LwpSigCheck) {
00144 lwpReady(LwpSigWaiter);
00145 LwpSigWaiter = NULL;
00146 }
00147 }