- Timestamp:
- Nov 6, 2004, 9:35:32 AM (21 years ago)
- Location:
- trunk/src/emx
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/emx/include/InnoTekLIBC/sharedpm.h
-
Property cvs2svn:cvs-rev
changed from
1.11
to1.12
r1614 r1615 109 109 110 110 111 /** The maximum number of signals a process can have pending on other processes concurrently. */ 112 #define __LIBC_SPM_SIGNALS_MAX_SENT 48 113 111 114 /** 112 115 * Signal (queued). … … 118 121 /** Pointer to the next signal. */ 119 122 struct __libc_SPMSignal *pNext; 123 /** Sender process. 124 * This is used to decrement the cSigsSent count of the sender. */ 125 pid_t pidSender; 126 120 127 /** Signal info. */ 121 128 siginfo_t Info; … … 277 284 * For signals which aren't queable only one signal can be queued. 278 285 */ 279 __LIBC_PSPMSIGNALpSigHead;280 /** Number of queued signals.281 * After it passes 48 signals, only SIGCHLD will be queued.282 * This means siqueue() won't work 100% according to spec. */283 unsigned cSigsQueued;286 volatile __LIBC_PSPMSIGNAL pSigHead; 287 /** Number of signals send. 288 * After __LIBC_SPM_SIGNALS_MAX_SENT signals only SIGCHLD will be allowed sent. 289 */ 290 volatile unsigned cSigsSent; 284 291 285 292 /** Reserved pool pointer field with default value 0. */ … … 653 660 654 661 /** 655 * De-queues one or more pending signals. 662 * Get the signal set of pending signals. 663 * 664 * @returns Number of pending signals on success. 665 * @returns 0 if no signals are pending. 666 * @returns Negative error code (errno.h) on failure. 667 * @param pSigSet Where to create the set of pending signals. 668 */ 669 int __libc_spmSigPending(sigset_t *pSigSet); 670 671 /** 672 * De-queues one or more pending signals of a specific type. 673 * 656 674 * @returns Number of de-queued signals on success. 657 675 * @returns Negative error code (errno.h) on failure. 676 * @param iSignalNo Signal type to dequeue. 658 677 * @param paSignals Where to store the signals. 659 678 * @param cSignals Size of the signal array. 660 679 * @param cbSignal Size of one signal entry. 661 680 */ 662 int __libc_spmSigDequeue( siginfo_t *paSignals, unsigned cSignals, size_t cbSignal);681 int __libc_spmSigDequeue(int iSignalNo, siginfo_t *paSignals, unsigned cSignals, size_t cbSignal); 663 682 664 683 -
Property cvs2svn:cvs-rev
changed from
-
trunk/src/emx/include/InnoTekLIBC/signals.h
-
Property cvs2svn:cvs-rev
changed from
1.2
to1.3
r1614 r1615 32 32 *******************************************************************************/ 33 33 /** @defgroup __libc_back_signalRaise_return __libc_back_signalRaise() returns. 34 * These are only valid for positive return values. 34 35 * @{ */ 35 36 /** Try restart any interrupted system call. */ … … 44 45 /** If set the passed in SIGQUEUED structure was used. */ 45 46 #define __LIBC_BSRR_USED_QUEUED 0x40 46 /** Failure. */47 #define __LIBC_BSRR_ERROR 0xffffff2248 47 /** @} */ 49 48 … … 94 93 int __libc_back_signalSuspend(void); 95 94 int __libc_back_signalWait(const struct timespec *pTimeout); 96 int __libc_back_signalVerifyPid(pid_t pid);97 int __libc_back_signalVerifyPGrp(pid_t pgid);98 int __libc_back_signalSendPid(pid_t pid, int iSignalNo);99 95 int __libc_back_signalSendPidOther(pid_t pid, int iSignalNo); 100 int __libc_back_signalSendPGrp(pid_t pgrp, int iSignalNo);101 96 int __libc_back_signalAction(int iSignalNo, const struct sigaction *pSigAct, struct sigaction *pSigActOld); 102 unsigned __libc_back_signalRaise(int iSignalNo, siginfo_t *pSigInfo, void *pvXcptOrQueued, unsigned fFlags);103 97 int __libc_back_signalRaisePoked(void *pvXcptParams, int tidPoker); 104 98 void __libc_back_signalOS2V1Handler16bit(unsigned short uSignal, unsigned short uArg); 105 99 void __libc_back_signalOS2V1Handler32bit(unsigned uSignal, unsigned uArg); 106 100 101 102 /** 103 * Raises a signal in the current process. 104 * 105 * @returns On success a flag mask out of the __LIBC_BSRR_* #defines is returned. 106 * @returns On failure a negative error code (errno.h) is returned. 107 * @param iSignalNo Signal to raise. 108 * @param pSigInfo Pointer to signal info for this signal. 109 * NULL is allowed. 110 * @param pvXcptOrQueued Exception handler parameter list. 111 * Or if __LIBC_BSRF_QUEUED is set, a pointer to locally malloced 112 * SIGQUEUED node. 113 * @param fFlags Flags of the #defines __LIBC_BSRF_* describing how to 114 * deliver the signal. 115 * 116 * @remark This Backend Signal API does NOT require the caller to own the signal semaphore. 117 */ 118 int __libc_Back_signalRaise(int iSignalNo, siginfo_t *pSigInfo, void *pvXcptOrQueued, unsigned fFlags); 119 120 /** 121 * Send a signal to a process. 122 * 123 * @returns 0 on if signal sent. 124 * @returns -errno on failure. 125 * 126 * @param pid Process Id of the process which the signal is to be sent to. 127 * @param iSignalNo The signal to send. 128 * @remark This Backend Signal API does NOT require the caller to own the signal semaphore. 129 */ 130 int __libc_Back_signalSendPid(pid_t pid, int iSignalNo); 131 132 /** 133 * Verify the existance of another process and that the current process 134 * is allowed to signal it. 135 * 136 * @return 0 on success. 137 * @return -ESRCH if pid doesn't exist. 138 * @return -EPERM if we aren't allowed to signal the pid. 139 * @param pid Process Id for the process which we wanna signal. 140 * @todo Do EPERM check, no ideas here yet. 141 * @remark This Backend Signal API does NOT require the caller to own the signal semaphore. 142 */ 143 int __libc_Back_signalVerifyPid(pid_t pid); 144 145 /** 146 * Not implemented. 147 * 148 * @returns -ENOSYS. 149 * @param pgrp Process group (positive). 150 * 0 means the process group of this process. 151 * 1 means all process in the system. 152 * @param iSignalNo Signal to send to all the processes in the group. 153 */ 154 int __libc_Back_signalSendPGrp(pid_t pgrp, int iSignalNo); 155 156 /** 157 * Verify the existance of a process group and that the current process 158 * is allowed to signal it. 159 * 160 * @return 0 on success. 161 * @return -ESRCH if pgid doesn't exist. 162 * @return -EPERM if we aren't allowed to signal the pgid. 163 * @param pgid Process group id which the current process intend to signal. 164 * @todo Do EPERM check, no ideas here yet. 165 * @remark This Backend Signal API does NOT require the caller to own the signal semaphore. 166 */ 167 int __libc_Back_signalVerifyPGrp(pid_t pgid); 168 169 107 170 __END_DECLS 108 171 -
Property cvs2svn:cvs-rev
changed from
-
trunk/src/emx/include/sys/signal.h
-
Property cvs2svn:cvs-rev
changed from
1.6
to1.7
r1614 r1615 147 147 /** Take signal on a registerd stack_t. */ 148 148 #define SA_ONSTACK 0x00000001 149 /** Restart system call on signal return. Not implemented on OS/2.*/149 /** Restart system call on signal return. */ 150 150 #define SA_RESTART 0x00000002 151 151 /** Reset signal handler to SIG_DFL when deliving the signal. */ … … 395 395 /** Timestamp when the signal was generated - LIBC extension. */ 396 396 unsigned si_timestamp; 397 /** Flags - LIBC extension. __LIBC_SI_* */ 398 unsigned si_flags; 397 399 /** Process sending the signal. */ 398 400 __pid_t si_pid; … … 412 414 int si_fd; 413 415 /** Reserve a little bit for future usage. */ 414 unsigned auReserved[ 4];416 unsigned auReserved[3]; 415 417 } siginfo_t; 418 419 #ifdef __BSD_VISIBLE 420 /** Signals LIBC flags. 421 * @{ */ 422 /** If set the signal was queue. */ 423 #define __LIBC_SI_QUEUED 0x00000001 424 /** @} */ 425 #endif 416 426 #endif 417 427 -
Property cvs2svn:cvs-rev
changed from
-
trunk/src/emx/src/lib/libc.def
-
Property cvs2svn:cvs-rev
changed from
1.72
to1.73
r1614 r1615 1230 1230 "__std_sigwait" @1252 1231 1231 "__std_sigwaitinfo" @1253 1232 "_gpSigQueueHead" @1254 1233 "_gpSigQueueTail" @1255 1234 "___libc_Back_signalRaise" @1256 1235 "___libc_Back_signalSendPGrp" @1257 1236 "___libc_Back_signalSendPid" @1258 1237 "___libc_Back_signalVerifyPGrp" @1259 1238 "___libc_Back_signalVerifyPid" @1260 -
Property cvs2svn:cvs-rev
changed from
-
trunk/src/emx/src/lib/process/kill.c
-
Property cvs2svn:cvs-rev
changed from
1.3
to1.4
r1614 r1615 75 75 */ 76 76 if (pid > 0) 77 rc = __libc_ back_signalVerifyPid(pid);77 rc = __libc_Back_signalVerifyPid(pid); 78 78 else /* (pid <= 0) */ 79 rc = __libc_ back_signalVerifyPGrp(-pid);79 rc = __libc_Back_signalVerifyPGrp(-pid); 80 80 if (!rc) 81 81 { … … 90 90 */ 91 91 if (pid > 0) 92 rc = __libc_ back_signalSendPid(pid, iSignalNo);92 rc = __libc_Back_signalSendPid(pid, iSignalNo); 93 93 else 94 rc = __libc_ back_signalSendPGrp(-pid, iSignalNo);94 rc = __libc_Back_signalSendPGrp(-pid, iSignalNo); 95 95 if (!rc) 96 96 LIBCLOG_RETURN_INT(0); -
Property cvs2svn:cvs-rev
changed from
-
trunk/src/emx/src/lib/sys/b_signalSendPGrp.c
-
Property cvs2svn:cvs-rev
changed from
1.1
to1.2
r1614 r1615 52 52 * @param iSignalNo Signal to send to all the processes in the group. 53 53 */ 54 int __libc_ back_signalSendPGrp(pid_t pgrp, int iSignalNo)54 int __libc_Back_signalSendPGrp(pid_t pgrp, int iSignalNo) 55 55 { 56 56 LIBC_ASSERTM_FAILED("__libc_back_signalSendPGrp is not implemented\n"); -
Property cvs2svn:cvs-rev
changed from
-
trunk/src/emx/src/lib/sys/b_signalSendPid.c
-
Property cvs2svn:cvs-rev
changed from
1.1
to1.2
r1614 r1615 53 53 * @remark This Backend Signal API does NOT require the caller to own the signal semaphore. 54 54 */ 55 int __libc_ back_signalSendPid(pid_t pid, int iSignalNo)55 int __libc_Back_signalSendPid(pid_t pid, int iSignalNo) 56 56 { 57 57 LIBCLOG_ENTER("pid=%d iSignalNo=%d\n", pid, iSignalNo); … … 59 59 60 60 /* 61 * Certain assumption are made.61 * Validate input. 62 62 */ 63 LIBC_ASSERTM(__SIGSET_SIG_VALID(iSignalNo), "Invalid signal no. %d\n", iSignalNo); 64 LIBC_ASSERTM(pid > 0, "Invalid pid %d\n", pid); 63 if (!__SIGSET_SIG_VALID(iSignalNo)) 64 { 65 LIBC_ASSERTM_FAILED("Invalid signal no. %d\n", iSignalNo); 66 LIBCLOG_RETURN_INT(-EINVAL); 67 } 68 if (pid < 0) 69 { 70 LIBC_ASSERTM_FAILED("Invalid pid %d\n", pid); 71 LIBCLOG_RETURN_INT(-EINVAL); 72 } 65 73 66 74 /* … … 71 79 else 72 80 { 73 int old_errno = 74 rc = __libc_back_signalRaise(iSignalNo, NULL, NULL, 0); 81 rc = __libc_Back_signalRaise(iSignalNo, NULL, NULL, 0); 75 82 if (rc > 0) 76 83 rc = 0; -
Property cvs2svn:cvs-rev
changed from
-
trunk/src/emx/src/lib/sys/b_signalVerifyPGrp.c
-
Property cvs2svn:cvs-rev
changed from
1.1
to1.2
r1614 r1615 51 51 * @remark This Backend Signal API does NOT require the caller to own the signal semaphore. 52 52 */ 53 int __libc_ back_signalVerifyPGrp(pid_t pgid)53 int __libc_Back_signalVerifyPGrp(pid_t pgid) 54 54 { 55 55 LIBCLOG_ENTER("pgid=%d\n", pgid); -
Property cvs2svn:cvs-rev
changed from
-
trunk/src/emx/src/lib/sys/b_signalVerifyPid.c
-
Property cvs2svn:cvs-rev
changed from
1.1
to1.2
r1614 r1615 51 51 * @remark This Backend Signal API does NOT require the caller to own the signal semaphore. 52 52 */ 53 int __libc_ back_signalVerifyPid(pid_t pid)53 int __libc_Back_signalVerifyPid(pid_t pid) 54 54 { 55 55 LIBCLOG_ENTER("pid=%d\n", pid); -
Property cvs2svn:cvs-rev
changed from
-
trunk/src/emx/src/lib/sys/exceptions.c
-
Property cvs2svn:cvs-rev
changed from
1.1
to1.2
r1614 r1615 77 77 __asm__ ("cld"); /* usual paranoia. */ 78 78 siginfo_t SigInfo = {0}; 79 int rc; /* return from __libc_ back_signalRaise() */79 int rc; /* return from __libc_Back_signalRaise() */ 80 80 81 81 if (pXcptRepRec->fHandlerFlags & (EH_UNWINDING | EH_EXIT_UNWIND)) … … 116 116 case XCPT_SIGNAL_KILLPROC: SigInfo.si_signo = SIGTERM; break; 117 117 } 118 rc = __libc_ back_signalRaise(SigInfo.si_signo, 0, &pXcptRepRec, __LIBC_BSRF_EXTERNAL);118 rc = __libc_Back_signalRaise(SigInfo.si_signo, 0, &pXcptRepRec, __LIBC_BSRF_EXTERNAL); 119 119 break; 120 120 } … … 156 156 SigInfo.si_addr = (void*)pXcptRepRec->ExceptionInfo[1]; /* accessed memory address */ 157 157 SigInfo.si_code = SEGV_ACCERR; 158 rc = __libc_ back_signalRaise(SigInfo.si_signo, &SigInfo, &pXcptRepRec, __LIBC_BSRF_HARDWARE | __LIBC_BSRF_THREAD);158 rc = __libc_Back_signalRaise(SigInfo.si_signo, &SigInfo, &pXcptRepRec, __LIBC_BSRF_HARDWARE | __LIBC_BSRF_THREAD); 159 159 break; 160 160 … … 166 166 SigInfo.si_code = BUS_ADRALN; 167 167 SigInfo.si_addr = (void*)pXcptRepRec->ExceptionInfo[2]; /* accessed memory address */ 168 rc = __libc_ back_signalRaise(SigInfo.si_signo, &SigInfo, &pXcptRepRec, __LIBC_BSRF_HARDWARE | __LIBC_BSRF_THREAD);168 rc = __libc_Back_signalRaise(SigInfo.si_signo, &SigInfo, &pXcptRepRec, __LIBC_BSRF_HARDWARE | __LIBC_BSRF_THREAD); 169 169 break; 170 170 … … 176 176 SigInfo.si_code = FPE_INTDIV; 177 177 SigInfo.si_addr = (void *)pCtx->ctx_RegEip; 178 rc = __libc_ back_signalRaise(SigInfo.si_signo, &SigInfo, &pXcptRepRec, __LIBC_BSRF_HARDWARE | __LIBC_BSRF_THREAD);178 rc = __libc_Back_signalRaise(SigInfo.si_signo, &SigInfo, &pXcptRepRec, __LIBC_BSRF_HARDWARE | __LIBC_BSRF_THREAD); 179 179 break; 180 180 … … 183 183 SigInfo.si_code = FPE_INTOVF; 184 184 SigInfo.si_addr = (void *)pCtx->ctx_RegEip; 185 rc = __libc_ back_signalRaise(SigInfo.si_signo, &SigInfo, &pXcptRepRec, __LIBC_BSRF_HARDWARE | __LIBC_BSRF_THREAD);185 rc = __libc_Back_signalRaise(SigInfo.si_signo, &SigInfo, &pXcptRepRec, __LIBC_BSRF_HARDWARE | __LIBC_BSRF_THREAD); 186 186 break; 187 187 … … 190 190 SigInfo.si_code = FPE_FLTDIV; 191 191 SigInfo.si_addr = (void *)pCtx->ctx_RegEip; 192 rc = __libc_ back_signalRaise(SigInfo.si_signo, &SigInfo, &pXcptRepRec, __LIBC_BSRF_HARDWARE | __LIBC_BSRF_THREAD);192 rc = __libc_Back_signalRaise(SigInfo.si_signo, &SigInfo, &pXcptRepRec, __LIBC_BSRF_HARDWARE | __LIBC_BSRF_THREAD); 193 193 break; 194 194 … … 197 197 SigInfo.si_code = FPE_FLTOVF; 198 198 SigInfo.si_addr = (void *)pCtx->ctx_RegEip; 199 rc = __libc_ back_signalRaise(SigInfo.si_signo, &SigInfo, &pXcptRepRec, __LIBC_BSRF_HARDWARE | __LIBC_BSRF_THREAD);199 rc = __libc_Back_signalRaise(SigInfo.si_signo, &SigInfo, &pXcptRepRec, __LIBC_BSRF_HARDWARE | __LIBC_BSRF_THREAD); 200 200 break; 201 201 … … 204 204 SigInfo.si_code = FPE_FLTUND; 205 205 SigInfo.si_addr = (void *)pCtx->ctx_RegEip; 206 rc = __libc_ back_signalRaise(SigInfo.si_signo, &SigInfo, &pXcptRepRec, __LIBC_BSRF_HARDWARE | __LIBC_BSRF_THREAD);206 rc = __libc_Back_signalRaise(SigInfo.si_signo, &SigInfo, &pXcptRepRec, __LIBC_BSRF_HARDWARE | __LIBC_BSRF_THREAD); 207 207 break; 208 208 … … 211 211 SigInfo.si_code = FPE_FLTINV; /* ??? */ 212 212 SigInfo.si_addr = (void *)pCtx->ctx_RegEip; 213 rc = __libc_ back_signalRaise(SigInfo.si_signo, &SigInfo, &pXcptRepRec, __LIBC_BSRF_HARDWARE | __LIBC_BSRF_THREAD);213 rc = __libc_Back_signalRaise(SigInfo.si_signo, &SigInfo, &pXcptRepRec, __LIBC_BSRF_HARDWARE | __LIBC_BSRF_THREAD); 214 214 break; 215 215 … … 218 218 SigInfo.si_code = FPE_FLTRES; 219 219 SigInfo.si_addr = (void *)pCtx->ctx_RegEip; 220 rc = __libc_ back_signalRaise(SigInfo.si_signo, &SigInfo, &pXcptRepRec, __LIBC_BSRF_HARDWARE | __LIBC_BSRF_THREAD);220 rc = __libc_Back_signalRaise(SigInfo.si_signo, &SigInfo, &pXcptRepRec, __LIBC_BSRF_HARDWARE | __LIBC_BSRF_THREAD); 221 221 break; 222 222 … … 225 225 SigInfo.si_code = FPE_FLTINV; 226 226 SigInfo.si_addr = (void *)pCtx->ctx_RegEip; 227 rc = __libc_ back_signalRaise(SigInfo.si_signo, &SigInfo, &pXcptRepRec, __LIBC_BSRF_HARDWARE | __LIBC_BSRF_THREAD);227 rc = __libc_Back_signalRaise(SigInfo.si_signo, &SigInfo, &pXcptRepRec, __LIBC_BSRF_HARDWARE | __LIBC_BSRF_THREAD); 228 228 break; 229 229 … … 232 232 SigInfo.si_code = FPE_FLTINV; /* ??? */ 233 233 SigInfo.si_addr = (void *)pCtx->ctx_RegEip; 234 rc = __libc_ back_signalRaise(SigInfo.si_signo, &SigInfo, &pXcptRepRec, __LIBC_BSRF_HARDWARE | __LIBC_BSRF_THREAD);234 rc = __libc_Back_signalRaise(SigInfo.si_signo, &SigInfo, &pXcptRepRec, __LIBC_BSRF_HARDWARE | __LIBC_BSRF_THREAD); 235 235 break; 236 236 … … 239 239 SigInfo.si_code = FPE_FLTSUB; 240 240 SigInfo.si_addr = (void *)pCtx->ctx_RegEip; 241 rc = __libc_ back_signalRaise(SigInfo.si_signo, &SigInfo, &pXcptRepRec, __LIBC_BSRF_HARDWARE | __LIBC_BSRF_THREAD);241 rc = __libc_Back_signalRaise(SigInfo.si_signo, &SigInfo, &pXcptRepRec, __LIBC_BSRF_HARDWARE | __LIBC_BSRF_THREAD); 242 242 break; 243 243 … … 250 250 SigInfo.si_code = ILL_ILLOPC; /* this could be any ILL_ILLO* */ 251 251 SigInfo.si_addr = (void *)pCtx->ctx_RegEip; 252 rc = __libc_ back_signalRaise(SigInfo.si_signo, &SigInfo, &pXcptRepRec, __LIBC_BSRF_HARDWARE | __LIBC_BSRF_THREAD);252 rc = __libc_Back_signalRaise(SigInfo.si_signo, &SigInfo, &pXcptRepRec, __LIBC_BSRF_HARDWARE | __LIBC_BSRF_THREAD); 253 253 break; 254 254 … … 257 257 SigInfo.si_code = ILL_ILLADR; /* ?????? */ 258 258 SigInfo.si_addr = (void *)pCtx->ctx_RegEip; 259 rc = __libc_ back_signalRaise(SigInfo.si_signo, &SigInfo, &pXcptRepRec, __LIBC_BSRF_HARDWARE | __LIBC_BSRF_THREAD);259 rc = __libc_Back_signalRaise(SigInfo.si_signo, &SigInfo, &pXcptRepRec, __LIBC_BSRF_HARDWARE | __LIBC_BSRF_THREAD); 260 260 break; 261 261 … … 264 264 SigInfo.si_code = ILL_PRVOPC; /* this could be ILL_PRVREG too. */ 265 265 SigInfo.si_addr = (void *)pCtx->ctx_RegEip; 266 rc = __libc_ back_signalRaise(SigInfo.si_signo, &SigInfo, &pXcptRepRec, __LIBC_BSRF_HARDWARE | __LIBC_BSRF_THREAD);266 rc = __libc_Back_signalRaise(SigInfo.si_signo, &SigInfo, &pXcptRepRec, __LIBC_BSRF_HARDWARE | __LIBC_BSRF_THREAD); 267 267 break; 268 268 … … 274 274 SigInfo.si_code = TRAP_TRACE; /* (?) */ 275 275 SigInfo.si_addr = (void *)pCtx->ctx_RegEip; 276 rc = __libc_ back_signalRaise(SigInfo.si_signo, &SigInfo, &pXcptRepRec, __LIBC_BSRF_HARDWARE | __LIBC_BSRF_THREAD);276 rc = __libc_Back_signalRaise(SigInfo.si_signo, &SigInfo, &pXcptRepRec, __LIBC_BSRF_HARDWARE | __LIBC_BSRF_THREAD); 277 277 break; 278 278 case XCPT_BREAKPOINT: … … 280 280 SigInfo.si_code = TRAP_BRKPT; 281 281 SigInfo.si_addr = (void *)pCtx->ctx_RegEip; 282 rc = __libc_ back_signalRaise(SigInfo.si_signo, &SigInfo, &pXcptRepRec, __LIBC_BSRF_HARDWARE | __LIBC_BSRF_THREAD);282 rc = __libc_Back_signalRaise(SigInfo.si_signo, &SigInfo, &pXcptRepRec, __LIBC_BSRF_HARDWARE | __LIBC_BSRF_THREAD); 283 283 break; 284 284 … … 291 291 /* 292 292 * This exception is special. We use it to poke threads with pending signals. 293 * __libc_ back_signalRaisePoked() will retest the flag from within the semaphore293 * __libc_Back_signalRaisePoked() will retest the flag from within the semaphore 294 294 * protection and returns __LIBC_BSRR_ERROR if it fails. 295 295 */ … … 297 297 if ( !pThrd 298 298 || !pThrd->fSigBeingPoked 299 || (rc = __libc_back_signalRaisePoked(&pXcptRepRec, pXcptRepRec->ExceptionInfo[0])) == __LIBC_BSRR_ERROR)299 || (rc = __libc_back_signalRaisePoked(&pXcptRepRec, pXcptRepRec->ExceptionInfo[0])) < 0) 300 300 { 301 301 #if 0 /** bird: no so sure about this. */ … … 329 329 } 330 330 331 return rc & __LIBC_BSRR_PASSITON? XCPT_CONTINUE_SEARCH : XCPT_CONTINUE_EXECUTION;331 return rc > 0 && (rc & __LIBC_BSRR_PASSITON) ? XCPT_CONTINUE_SEARCH : XCPT_CONTINUE_EXECUTION; 332 332 } 333 333 -
Property cvs2svn:cvs-rev
changed from
-
trunk/src/emx/src/lib/sys/sharedpm.c
-
Property cvs2svn:cvs-rev
changed from
1.12
to1.13
r1614 r1615 895 895 * This is mostly because we wanna crash before we take the sem. 896 896 */ 897 #ifdef SIGRTMAX /* just make it build. */898 897 if (pSignal->si_signo <= 0 || pSignal->si_signo > SIGRTMAX) 899 898 { … … 901 900 LIBCLOG_RETURN_INT(-EINVAL); 902 901 } 903 #endif904 902 if (pSignal->auReserved[(sizeof(pSignal->auReserved) / sizeof(pSignal->auReserved[0])) - 1]) 905 903 { … … 939 937 * Check that we're not exceeding any per process or system limits. 940 938 */ 941 if (!gpSPMHdr->cSigMaxActive) 942 gpSPMHdr->cSigMaxActive = 1024; 943 if ( ( gpSPMHdr->cSigActive < gpSPMHdr->cSigMaxActive 944 && pProcess->cSigsQueued < 48) 939 if ( ( gpSPMHdr->cSigActive < gpSPMHdr->cSigMaxActive 940 && gpSPMSelf->cSigsSent < __LIBC_SPM_SIGNALS_MAX_SENT) 945 941 || pSignal->si_signo == SIGCHLD) 946 942 { … … 968 964 pSig->cb = sizeof(*pSig); 969 965 } 966 /* 967 * Copy the data and insert it into the queue. 968 */ 970 969 if (pSig) 971 970 { 972 /* 973 * Copy the data and insert it into the queue. 974 */ 975 pSig->pNext = pProcess->pSigHead; 976 pSig->Info = *pSignal; 977 pProcess->pSigHead = pSig; 978 pProcess->cSigsQueued++; 971 pSig->pNext = NULL; 972 pSig->pidSender = gpSPMSelf->pid; 973 pSig->Info = *pSignal; 974 975 /* insert */ 976 if (!pProcess->pSigHead) 977 pProcess->pSigHead = pSig; 978 else 979 { 980 __LIBC_PSPMSIGNAL pSigLast = pProcess->pSigHead; 981 while (pSigLast->pNext) 982 pSigLast = pSigLast->pNext; 983 pSigLast->pNext = pSig; 984 } 985 986 /* update statistics */ 987 if (pProcess != gpSPMSelf) 988 gpSPMSelf->cSigsSent++; 979 989 gpSPMHdr->cSigActive++; 980 rc = 0;981 990 } 982 991 else … … 988 997 else 989 998 { 990 LIBCLOG_MSG("Limit reached: cSigActive=%d cSigMaxActive=%d cSigs Queued=%d (max 48)\n",991 gpSPMHdr->cSigActive, gpSPMHdr->cSigMaxActive, pProcess->cSigs Queued);999 LIBCLOG_MSG("Limit reached: cSigActive=%d cSigMaxActive=%d cSigsSent=%d (max %d)\n", 1000 gpSPMHdr->cSigActive, gpSPMHdr->cSigMaxActive, pProcess->cSigsSent, __LIBC_SPM_SIGNALS_MAX_SENT); 992 1001 rc = -EAGAIN; 993 1002 } … … 1008 1017 1009 1018 /** 1010 * De-queues one or more pending signals. 1011 * @returns Number of de-queued signals on success. 1019 * Get the signal set of pending signals. 1020 * 1021 * @returns Number of pending signals on success. 1022 * @returns 0 if no signals are pending. 1012 1023 * @returns Negative error code (errno.h) on failure. 1013 * @param paSignals Where to store the signals. 1014 * @param cSignals Size of the signal array. 1015 * @param cbSignal Size of one signal entry. 1016 */ 1017 int __libc_spmSigDequeue(siginfo_t *paSignals, unsigned cSignals, size_t cbSignal) 1018 { 1019 LIBCLOG_ENTER("paSignals=%p cSignals=%d cbSignal=%d\n", (void *)paSignals, cSignals, cbSignal); 1020 1021 /* 1022 * Validate input. 1023 */ 1024 if (sizeof(siginfo_t) > cbSignal) 1025 { 1026 LIBC_ASSERTM_FAILED("Invalid siginfo_t size: cbSignal=%d sizeof(siginfo_t)=%d\n", cbSignal, sizeof(siginfo_t)); 1027 LIBCLOG_RETURN_INT(-EINVAL); 1028 } 1029 bzero(paSignals, cSignals * cbSignal); /* This'll trap if it's wrong :-) */ 1024 * @param pSigSet Where to create the set of pending signals. 1025 */ 1026 int __libc_spmSigPending(sigset_t *pSigSet) 1027 { 1028 LIBCLOG_ENTER("pSigSet=%p\n", (void *)pSigSet); 1029 1030 /* 1031 * Paranoid as always, work on stack copy. 1032 */ 1033 sigset_t SigSet; 1034 __SIGSET_EMPTY(&SigSet); 1030 1035 1031 1036 /* … … 1040 1045 * De-queue signals one-by-one. 1041 1046 */ 1042 while (gpSPMSelf->pSigHead && cSignals-- > 0) 1043 { 1047 __LIBC_PSPMSIGNAL pSig = gpSPMSelf->pSigHead; 1048 while (pSig) 1049 { 1050 rc++; 1051 __SIGSET_SET(&SigSet, pSig->Info.si_signo); 1052 pSig = pSig->pNext; 1053 } 1054 1055 spmReleaseMutex(&RegRec); 1056 *pSigSet = SigSet; 1057 LIBCLOG_RETURN_MSG(rc, "ret %d *pSigSet={%08lx %08lx}", rc, pSigSet->__bitmap[1], pSigSet->__bitmap[0]); 1058 } 1059 1060 /** 1061 * De-queues one or more pending signals of a specific type. 1062 * 1063 * @returns Number of de-queued signals on success. 1064 * @returns Negative error code (errno.h) on failure. 1065 * @param iSignalNo Signal type to dequeue. 1066 * @param paSignals Where to store the signals. 1067 * @param cSignals Size of the signal array. 1068 * @param cbSignal Size of one signal entry. 1069 */ 1070 int __libc_spmSigDequeue(int iSignalNo, siginfo_t *paSignals, unsigned cSignals, size_t cbSignal) 1071 { 1072 LIBCLOG_ENTER("paSignals=%p cSignals=%d cbSignal=%d\n", (void *)paSignals, cSignals, cbSignal); 1073 1074 /* 1075 * Validate input. 1076 */ 1077 if (sizeof(siginfo_t) > cbSignal) 1078 { 1079 LIBC_ASSERTM_FAILED("Invalid siginfo_t size: cbSignal=%d sizeof(siginfo_t)=%d\n", cbSignal, sizeof(siginfo_t)); 1080 LIBCLOG_RETURN_INT(-EINVAL); 1081 } 1082 bzero(paSignals, cSignals * cbSignal); /* This'll trap if it's wrong :-) */ 1083 1084 /* 1085 * Request sem. 1086 */ 1087 __LIBC_SPMXCPTREGREC RegRec; 1088 int rc = spmRequestMutex(&RegRec); 1089 if (rc) 1090 LIBCLOG_RETURN_INT(rc); 1091 1092 /* 1093 * De-queue signals one-by-one. 1094 */ 1095 __LIBC_PSPMSIGNAL pSigPrev = NULL; 1096 __LIBC_PSPMSIGNAL pSig = gpSPMSelf->pSigHead; 1097 while (pSig && cSignals-- > 0) 1098 { 1099 /* 1100 * Find it. 1101 */ 1102 while (pSig && pSig->Info.si_signo != iSignalNo) 1103 { 1104 pSigPrev = pSig; 1105 pSig = pSig->pNext; 1106 } 1107 if (!pSig) 1108 break; 1109 1044 1110 /* 1045 1111 * Copy it. 1046 1112 */ 1047 __LIBC_PSPMSIGNAL pSig = gpSPMSelf->pSigHead;1048 1113 if (pSig->cb >= sizeof(siginfo_t)) 1049 1114 *paSignals = pSig->Info; … … 1054 1119 * Unlink it and free it. 1055 1120 */ 1056 gpSPMSelf->pSigHead = pSig->pNext; 1057 if (gpSPMSelf->cSigsQueued > 0) 1058 gpSPMSelf->cSigsQueued--; 1121 /* statistics */ 1122 if (gpSPMSelf->pid != pSig->pidSender) 1123 { 1124 __LIBC_PSPMPROCESS pSender = spmQueryProcessInState(pSig->pidSender, __LIBC_PROCSTATE_ALIVE); 1125 if (pSender) 1126 pSender->cSigsSent--; 1127 } 1128 gpSPMHdr->cSigActive--; 1129 1130 /* unlink */ 1131 if (pSigPrev) 1132 pSigPrev->pNext = pSig->pNext; 1133 else 1134 gpSPMSelf->pSigHead = pSig->pNext; 1135 1136 /* free */ 1137 __LIBC_PSPMSIGNAL pSigNext = pSig->pNext; 1059 1138 if (gpSPMHdr->cSigFree < 32) 1060 1139 { … … 1066 1145 spmFree(pSig); 1067 1146 1068 /* next */ 1147 /* 1148 * Next. 1149 */ 1150 pSig = pSigNext; 1151 paSignals = (siginfo_t *)((char *)paSignals + cbSignal); 1069 1152 rc++; 1070 paSignals = (siginfo_t *)((char *)paSignals + cbSignal);1071 1153 } 1072 1154 … … 1410 1492 rc = DosGetNamedSharedMem(&pv, (PCSZ)SPM_MEMORY_NAME, PAG_READ | PAG_WRITE); 1411 1493 if (!rc) 1494 { 1412 1495 gpSPMHdr = (__LIBC_PSPMHEADER)pv; 1496 if (!gpSPMHdr->cSigMaxActive) 1497 gpSPMHdr->cSigMaxActive = 1024; 1498 } 1413 1499 else 1414 1500 { -
Property cvs2svn:cvs-rev
changed from
-
trunk/src/emx/src/lib/sys/signals.c
-
Property cvs2svn:cvs-rev
changed from
1.1
to1.2
r1614 r1615 30 30 * LIBC fully implements the posix signal handling. 31 31 * 32 * Interprocess signaling is somewhat compatible with EMX, that is 33 * some of the EMX signals didn't have the same values as BSD, and most 34 * of them weren't implemented. Thus sending signals to non LIBC processes 35 * even EMX processes may not work as expected. 36 * 37 * @todo write more! 32 * Interprocess signaling is only available when target is linked to LIBCxyz.DLL. 33 * When the target is a LIBC process the signal is queued in SPM before the 34 * target process is actually poked. When the target is a non-LIBC process the 35 * signal is attempted converted to EMX and signaled in the EMX fashion. This 36 * obviously means that certain restrictions applies when signaling EMX processes. 37 * 38 * 39 * Signals are pending in on of three places depending on how fare they are 40 * scheduled. Scheduling levels and pending location: 41 * - Pending on the SPM process, not scheduled. 42 * - Pending in process wide queues, not scheduled. 43 * - Pending on thread, scheduled. 44 * 45 * There are generally speaking fource sources signals: 46 * - Internal software signals in current thread, raise()/kill(getpid())/sigqueue(getpid()). 47 * - Other thread, pthread_kill(). This needs no process scheduling, only 48 * priority ordering on delivery. 49 * - OS/2 hardware exceptions. Generally no scheduling required, these must be 50 * handled promptly on the current thread. 51 * - External signals, queued in SPM, EMX signals, or OS/2 signal exceptions. 52 * 53 * When talking scheduling this means we'll reschedule the entire process when: 54 * - an external signal arrives. 55 * - an internal software signal occurs (raise/kill/sigqueue). 56 * - the signal mask of a thread changes. 57 * Two cases, 1) unblocking a signal no, 2) blocking signal no with 58 * pending signal. The 2nd case is very uncommon and could perhaps be 59 * ignored or handled differently. -bird: we do that now! 60 * 38 61 * 39 62 */ … … 69 92 70 93 /** @defgroup libc_back_signals_properties Signal Properties 94 * The return actions are ordered by precendece. 71 95 * @{ */ 96 /** Return Action: Terminate. */ 97 #define SPR_KILL 0x0000 72 98 /** Return Action: Restart instruction. */ 73 #define SPR_RESTART 0x0000 74 /** Return Action: Next exception handler. */ 75 #define SPR_NEXT 0x0001 76 /** Return Action: Terminate if primary exception handler, next exception handler if not. */ 77 #define SPR_NEXT_KILL 0x0002 78 /** Return Action: Terminate. */ 79 #define SPR_KILL 0x0003 99 #define SPR_CONTINUE 0x0001 80 100 /** Return Action Mask */ 81 #define SPR_MASK 0x000 3101 #define SPR_MASK 0x0001 82 102 83 103 /** Action: Ignore the signal. */ … … 110 130 /** Property: This signal can be queued. */ 111 131 #define SPP_QUEUED 0x0800 132 /** Property: Signal action cannot be automatically reset in SysV fashion. */ 133 #define SPP_NORESET 0x1000 112 134 /** @} */ 113 135 … … 166 188 167 189 168 /** A Signal queue.169 * This is created per signal number and is ordered in a FIFO order,170 * inserting at the tail and removing from the head.171 */172 typedef struct SignalQueue173 {174 /** Pointer to the head. */175 PSIGQUEUED pHead;176 /** Pointer to the tail. */177 PSIGQUEUED pTail;178 } SIGQUEUE, *PSIGQUEUE;179 180 181 190 /** Thread enumeration state data. 182 * Used by signalSchedule () when enumerating threads.191 * Used by signalScheduleThread() when enumerating threads. 183 192 */ 184 193 typedef struct SigSchedEnumParam … … 205 214 static HMTX ghmtxSignals; 206 215 216 /** Signal Wait Event Semaphore. 217 * This is an event semaphore which will never be posted (unless we wanna resolve 218 * some nasty deadlock in the future) but is used to wait for a signal to arrive. 219 * When a signal arrives the wait will be interrupted to allow for execution of 220 * the exception and signal processing. DosWaitEventSem will return ERROR_INTERRUPT. 221 */ 222 static HEV ghevWait; 223 207 224 /** Signal Properties. 208 225 * Describes the default actions of a signal. … … 211 228 { 212 229 /* return action | default action | property [|anotherprop] */ 213 SPR_ RESTART | SPA_IGNORE,/* SIG0 */214 SPR_ RESTART | SPA_KILL | SPP_ANYTHRD,/* SIGHUP 1 /-- POSIX: Hangup */215 SPR_ RESTART | SPA_KILL | SPP_ANYTHRD,/* SIGINT 2 /-- ANSI: Interrupt (Ctrl-C) */216 SPR_ RESTART | SPA_CORE | SPP_ANYTHRD,/* SIGQUIT 3 /-- POSIX: Quit */217 SPR_ RESTART | SPA_NEXT_CORE,/* SIGILL 4 /-- ANSI: Illegal instruction */218 SPR_ RESTART | SPA_NEXT_KILL,/* SIGTRAP 5 /-- POSIX: Single step (debugging) */219 SPR_KILL | SPA_CORE,/* SIGABRT 6 /-- ANSI: abort () */220 SPR_ RESTART | SPA_CORE | SPP_ANYTHRD,/* SIGEMT 7 /-- BSD: EMT instruction */221 SPR_ RESTART | SPA_NEXT_CORE,/* SIGFPE 8 /-- ANSI: Floating point */222 SPR_KILL | SPA_KILL | SPP_ANYTHRD | SPP_NOBLOCK | SPP_NOCATCH,/* SIGKILL 9 /-- POSIX: Kill process */223 SPR_ RESTART | SPA_CORE,/* SIGBUS 10 /-- BSD 4.2: Bus error */224 SPR_ RESTART | SPA_NEXT_CORE,/* SIGSEGV 11 /-- ANSI: Segmentation fault */225 SPR_ RESTART | SPA_CORE,/* SIGSYS 12 /-- Invalid argument to system call */226 SPR_ RESTART | SPA_KILL | SPP_ANYTHRD,/* SIGPIPE 13 /-- POSIX: Broken pipe. */227 SPR_ RESTART | SPA_KILL | SPP_ANYTHRD,/* SIGALRM 14 /-- POSIX: Alarm. */228 SPR_ RESTART | SPA_NEXT_KILL | SPP_ANYTHRD,/* SIGTERM 15 /-- ANSI: Termination, process killed */229 SPR_ RESTART | SPA_IGNORE,/* SIGURG 16 /-- POSIX/BSD: urgent condition on IO channel */230 SPR_ RESTART | SPA_STOP | SPP_ANYTHRD | SPP_NOBLOCK | SPP_NOCATCH,/* SIGSTOP 17 /-- POSIX: Sendable stop signal not from tty. unblockable. */231 SPR_ RESTART | SPA_STOPTTY | SPP_ANYTHRD,/* SIGTSTP 18 /-- POSIX: Stop signal from tty. */232 SPR_ RESTART | SPA_RESUME | SPP_ANYTHRD,/* SIGCONT 19 /-- POSIX: Continue a stopped process. */233 SPR_ RESTART | SPA_IGNORE | SPP_ANYTHRD | SPP_QUEUED,/* SIGCHLD 20 /-- POSIX: Death or stop of a child process. (EMX: 18) */234 SPR_ RESTART | SPA_STOPTTY | SPP_ANYTHRD,/* SIGTTIN 21 /-- POSIX: To readers pgrp upon background tty read. */235 SPR_ RESTART | SPA_STOPTTY | SPP_ANYTHRD,/* SIGTTOU 22 /-- POSIX: To readers pgrp upon background tty write. */236 SPR_ RESTART | SPA_IGNORE | SPP_ANYTHRD,/* SIGIO 23 /-- BSD: Input/output possible signal. */237 SPR_ RESTART | SPA_KILL,/* SIGXCPU 24 /-- BSD 4.2: Exceeded CPU time limit. */238 SPR_ RESTART | SPA_KILL,/* SIGXFSZ 25 /-- BSD 4.2: Exceeded file size limit. */239 SPR_ RESTART | SPA_KILL | SPP_ANYTHRD,/* SIGVTALRM 26 /-- BSD 4.2: Virtual time alarm. */240 SPR_ RESTART | SPA_KILL | SPP_ANYTHRD,/* SIGPROF 27 /-- BSD 4.2: Profiling time alarm. */241 SPR_ RESTART | SPA_IGNORE | SPP_ANYTHRD,/* SIGWINCH 28 /-- BSD 4.3: Window size change (not implemented). */242 SPR_ RESTART | SPA_NEXT_KILL | SPP_ANYTHRD,/* SIGBREAK 29 /-- OS/2: Break (Ctrl-Break). (EMX: 21) */243 SPR_ RESTART | SPA_KILL | SPP_ANYTHRD,/* SIGUSR1 30 /-- POSIX: User-defined signal #1 */244 SPR_ RESTART | SPA_KILL | SPP_ANYTHRD,/* SIGUSR2 31 /-- POSIX: User-defined signal #2 */245 SPR_ RESTART | SPA_NEXT_KILL | SPP_ANYTHRD,/* SIGBREAK 32 /-- OS/2: Break (Ctrl-Break). (EMX: 21) */230 SPR_CONTINUE | SPA_IGNORE, /* SIG0 */ 231 SPR_CONTINUE | SPA_KILL | SPP_ANYTHRD, /* SIGHUP 1 /-- POSIX: Hangup */ 232 SPR_CONTINUE | SPA_KILL | SPP_ANYTHRD, /* SIGINT 2 /-- ANSI: Interrupt (Ctrl-C) */ 233 SPR_CONTINUE | SPA_CORE | SPP_ANYTHRD, /* SIGQUIT 3 /-- POSIX: Quit */ 234 SPR_CONTINUE | SPA_NEXT_CORE | SPP_NORESET, /* SIGILL 4 /-- ANSI: Illegal instruction */ 235 SPR_CONTINUE | SPA_NEXT_KILL | SPP_NORESET, /* SIGTRAP 5 /-- POSIX: Single step (debugging) */ 236 SPR_KILL | SPA_CORE, /* SIGABRT 6 /-- ANSI: abort () */ 237 SPR_CONTINUE | SPA_CORE | SPP_ANYTHRD, /* SIGEMT 7 /-- BSD: EMT instruction */ 238 SPR_CONTINUE | SPA_NEXT_CORE, /* SIGFPE 8 /-- ANSI: Floating point */ 239 SPR_KILL | SPA_KILL | SPP_ANYTHRD | SPP_NOBLOCK | SPP_NOCATCH, /* SIGKILL 9 /-- POSIX: Kill process */ 240 SPR_CONTINUE | SPA_CORE, /* SIGBUS 10 /-- BSD 4.2: Bus error */ 241 SPR_CONTINUE | SPA_NEXT_CORE, /* SIGSEGV 11 /-- ANSI: Segmentation fault */ 242 SPR_CONTINUE | SPA_CORE, /* SIGSYS 12 /-- Invalid argument to system call */ 243 SPR_CONTINUE | SPA_KILL | SPP_ANYTHRD, /* SIGPIPE 13 /-- POSIX: Broken pipe. */ 244 SPR_CONTINUE | SPA_KILL | SPP_ANYTHRD, /* SIGALRM 14 /-- POSIX: Alarm. */ 245 SPR_CONTINUE | SPA_NEXT_KILL | SPP_ANYTHRD, /* SIGTERM 15 /-- ANSI: Termination, process killed */ 246 SPR_CONTINUE | SPA_IGNORE, /* SIGURG 16 /-- POSIX/BSD: urgent condition on IO channel */ 247 SPR_CONTINUE | SPA_STOP | SPP_ANYTHRD | SPP_NOBLOCK | SPP_NOCATCH, /* SIGSTOP 17 /-- POSIX: Sendable stop signal not from tty. unblockable. */ 248 SPR_CONTINUE | SPA_STOPTTY | SPP_ANYTHRD, /* SIGTSTP 18 /-- POSIX: Stop signal from tty. */ 249 SPR_CONTINUE | SPA_RESUME | SPP_ANYTHRD, /* SIGCONT 19 /-- POSIX: Continue a stopped process. */ 250 SPR_CONTINUE | SPA_IGNORE | SPP_ANYTHRD | SPP_QUEUED, /* SIGCHLD 20 /-- POSIX: Death or stop of a child process. (EMX: 18) */ 251 SPR_CONTINUE | SPA_STOPTTY | SPP_ANYTHRD, /* SIGTTIN 21 /-- POSIX: To readers pgrp upon background tty read. */ 252 SPR_CONTINUE | SPA_STOPTTY | SPP_ANYTHRD, /* SIGTTOU 22 /-- POSIX: To readers pgrp upon background tty write. */ 253 SPR_CONTINUE | SPA_IGNORE | SPP_ANYTHRD, /* SIGIO 23 /-- BSD: Input/output possible signal. */ 254 SPR_CONTINUE | SPA_KILL, /* SIGXCPU 24 /-- BSD 4.2: Exceeded CPU time limit. */ 255 SPR_CONTINUE | SPA_KILL, /* SIGXFSZ 25 /-- BSD 4.2: Exceeded file size limit. */ 256 SPR_CONTINUE | SPA_KILL | SPP_ANYTHRD, /* SIGVTALRM 26 /-- BSD 4.2: Virtual time alarm. */ 257 SPR_CONTINUE | SPA_KILL | SPP_ANYTHRD, /* SIGPROF 27 /-- BSD 4.2: Profiling time alarm. */ 258 SPR_CONTINUE | SPA_IGNORE | SPP_ANYTHRD, /* SIGWINCH 28 /-- BSD 4.3: Window size change (not implemented). */ 259 SPR_CONTINUE | SPA_NEXT_KILL | SPP_ANYTHRD, /* SIGBREAK 29 /-- OS/2: Break (Ctrl-Break). (EMX: 21) */ 260 SPR_CONTINUE | SPA_KILL | SPP_ANYTHRD, /* SIGUSR1 30 /-- POSIX: User-defined signal #1 */ 261 SPR_CONTINUE | SPA_KILL | SPP_ANYTHRD, /* SIGUSR2 31 /-- POSIX: User-defined signal #2 */ 262 SPR_CONTINUE | SPA_NEXT_KILL | SPP_ANYTHRD, /* SIGBREAK 32 /-- OS/2: Break (Ctrl-Break). (EMX: 21) */ 246 263 /* real time signals */ 247 SPR_ RESTART | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED,/* SIGRTMIN + 0 */248 SPR_ RESTART | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED,/* SIGRTMIN + 1 */249 SPR_ RESTART | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED,/* SIGRTMIN + 2 */250 SPR_ RESTART | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED,/* SIGRTMIN + 3 */251 SPR_ RESTART | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED,/* SIGRTMIN + 4 */252 SPR_ RESTART | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED,/* SIGRTMIN + 5 */253 SPR_ RESTART | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED,/* SIGRTMIN + 6 */254 SPR_ RESTART | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED,/* SIGRTMIN + 7 */255 SPR_ RESTART | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED,/* SIGRTMIN + 8 */256 SPR_ RESTART | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED,/* SIGRTMIN + 9 */257 SPR_ RESTART | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED,/* SIGRTMIN + 10 */258 SPR_ RESTART | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED,/* SIGRTMIN + 11 */259 SPR_ RESTART | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED,/* SIGRTMIN + 12 */260 SPR_ RESTART | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED,/* SIGRTMIN + 13 */261 SPR_ RESTART | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED,/* SIGRTMIN + 14 */262 SPR_ RESTART | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED,/* SIGRTMIN + 15 */263 SPR_ RESTART | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED,/* SIGRTMIN + 16 */264 SPR_ RESTART | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED,/* SIGRTMIN + 17 */265 SPR_ RESTART | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED,/* SIGRTMIN + 18 */266 SPR_ RESTART | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED,/* SIGRTMIN + 19 */267 SPR_ RESTART | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED,/* SIGRTMIN + 20 */268 SPR_ RESTART | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED,/* SIGRTMIN + 21 */269 SPR_ RESTART | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED,/* SIGRTMIN + 22 */270 SPR_ RESTART | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED,/* SIGRTMIN + 23 */271 SPR_ RESTART | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED,/* SIGRTMIN + 24 */272 SPR_ RESTART | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED,/* SIGRTMIN + 25 */273 SPR_ RESTART | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED,/* SIGRTMIN + 26 */274 SPR_ RESTART | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED,/* SIGRTMIN + 27 */275 SPR_ RESTART | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED,/* SIGRTMIN + 28 */276 SPR_ RESTART | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED,/* SIGRTMIN + 29 */277 SPR_ RESTART | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED,/* SIGRTMIN + 30 == SIGRTMAX */264 SPR_CONTINUE | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED, /* SIGRTMIN + 0 */ 265 SPR_CONTINUE | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED, /* SIGRTMIN + 1 */ 266 SPR_CONTINUE | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED, /* SIGRTMIN + 2 */ 267 SPR_CONTINUE | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED, /* SIGRTMIN + 3 */ 268 SPR_CONTINUE | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED, /* SIGRTMIN + 4 */ 269 SPR_CONTINUE | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED, /* SIGRTMIN + 5 */ 270 SPR_CONTINUE | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED, /* SIGRTMIN + 6 */ 271 SPR_CONTINUE | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED, /* SIGRTMIN + 7 */ 272 SPR_CONTINUE | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED, /* SIGRTMIN + 8 */ 273 SPR_CONTINUE | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED, /* SIGRTMIN + 9 */ 274 SPR_CONTINUE | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED, /* SIGRTMIN + 10 */ 275 SPR_CONTINUE | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED, /* SIGRTMIN + 11 */ 276 SPR_CONTINUE | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED, /* SIGRTMIN + 12 */ 277 SPR_CONTINUE | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED, /* SIGRTMIN + 13 */ 278 SPR_CONTINUE | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED, /* SIGRTMIN + 14 */ 279 SPR_CONTINUE | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED, /* SIGRTMIN + 15 */ 280 SPR_CONTINUE | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED, /* SIGRTMIN + 16 */ 281 SPR_CONTINUE | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED, /* SIGRTMIN + 17 */ 282 SPR_CONTINUE | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED, /* SIGRTMIN + 18 */ 283 SPR_CONTINUE | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED, /* SIGRTMIN + 19 */ 284 SPR_CONTINUE | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED, /* SIGRTMIN + 20 */ 285 SPR_CONTINUE | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED, /* SIGRTMIN + 21 */ 286 SPR_CONTINUE | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED, /* SIGRTMIN + 22 */ 287 SPR_CONTINUE | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED, /* SIGRTMIN + 23 */ 288 SPR_CONTINUE | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED, /* SIGRTMIN + 24 */ 289 SPR_CONTINUE | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED, /* SIGRTMIN + 25 */ 290 SPR_CONTINUE | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED, /* SIGRTMIN + 26 */ 291 SPR_CONTINUE | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED, /* SIGRTMIN + 27 */ 292 SPR_CONTINUE | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED, /* SIGRTMIN + 28 */ 293 SPR_CONTINUE | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED, /* SIGRTMIN + 29 */ 294 SPR_CONTINUE | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED, /* SIGRTMIN + 30 == SIGRTMAX */ 278 295 }; 279 296 … … 354 371 * All access to this set is protected by the signal semaphore. 355 372 */ 356 sigset_t __libc_gSignalPending = {{0,0}}; 357 358 /** Signal Queues. 359 * All access to this array is protected by the signal semaphore. 360 */ 361 static SIGQUEUE gaSignalQueues[__SIGSET_MAXSIGNALS] = 362 { 363 { NULL, NULL }, /* SIG0 */ 364 { NULL, NULL }, /* SIGHUP 1 /-- POSIX: Hangup */ 365 { NULL, NULL }, /* SIGINT 2 /-- ANSI: Interrupt (Ctrl-C) */ 366 { NULL, NULL }, /* SIGQUIT 3 /-- POSIX: Quit */ 367 { NULL, NULL }, /* SIGILL 4 /-- ANSI: Illegal instruction */ 368 { NULL, NULL }, /* SIGTRAP 5 /-- POSIX: Single step (debugging) */ 369 { NULL, NULL }, /* SIGABRT 6 /-- ANSI: abort () */ 370 { NULL, NULL }, /* SIGEMT 7 /-- BSD: EMT instruction */ 371 { NULL, NULL }, /* SIGFPE 8 /-- ANSI: Floating point */ 372 { NULL, NULL }, /* SIGKILL 9 /-- POSIX: Kill process */ 373 { NULL, NULL }, /* SIGBUS 10 /-- BSD 4.2: Bus error */ 374 { NULL, NULL }, /* SIGSEGV 11 /-- ANSI: Segmentation fault */ 375 { NULL, NULL }, /* SIGSYS 12 /-- Invalid argument to system call */ 376 { NULL, NULL }, /* SIGPIPE 13 /-- POSIX: Broken pipe. */ 377 { NULL, NULL }, /* SIGALRM 14 /-- POSIX: Alarm. */ 378 { NULL, NULL }, /* SIGTERM 15 /-- ANSI: Termination, process killed */ 379 { NULL, NULL }, /* SIGURG 16 /-- POSIX/BSD: urgent condition on IO channel */ 380 { NULL, NULL }, /* SIGSTOP 17 /-- POSIX: Sendable stop signal not from tty. unblockable. */ 381 { NULL, NULL }, /* SIGTSTP 18 /-- POSIX: Stop signal from tty. */ 382 { NULL, NULL }, /* SIGCONT 19 /-- POSIX: Continue a stopped process. */ 383 { NULL, NULL }, /* SIGCHLD 20 /-- POSIX: Death or stop of a child process. (EMX: 18) */ 384 { NULL, NULL }, /* SIGTTIN 21 /-- POSIX: To readers pgrp upon background tty read. */ 385 { NULL, NULL }, /* SIGTTOU 22 /-- POSIX: To readers pgrp upon background tty write. */ 386 { NULL, NULL }, /* SIGIO 23 /-- BSD: Input/output possible signal. */ 387 { NULL, NULL }, /* SIGXCPU 24 /-- BSD 4.2: Exceeded CPU time limit. */ 388 { NULL, NULL }, /* SIGXFSZ 25 /-- BSD 4.2: Exceeded file size limit. */ 389 { NULL, NULL }, /* SIGVTALRM 26 /-- BSD 4.2: Virtual time alarm. */ 390 { NULL, NULL }, /* SIGPROF 27 /-- BSD 4.2: Profiling time alarm. */ 391 { NULL, NULL }, /* SIGWINCH 28 /-- BSD 4.3: Window size change (not implemented). */ 392 { NULL, NULL }, /* SIGINFO 29 /-- BSD 4.3: Information request. */ 393 { NULL, NULL }, /* SIGUSR1 30 /-- POSIX: User-defined signal #1 */ 394 { NULL, NULL }, /* SIGUSR2 31 /-- POSIX: User-defined signal #2 */ 395 { NULL, NULL }, /* SIGBREAK 30 /-- OS/2: Break (Ctrl-Break). (EMX: 21) */ 396 /* realtime signals */ 397 { NULL, NULL }, /* SIGRTMIN + 0 */ 398 { NULL, NULL }, /* SIGRTMIN + 1 */ 399 { NULL, NULL }, /* SIGRTMIN + 2 */ 400 { NULL, NULL }, /* SIGRTMIN + 3 */ 401 { NULL, NULL }, /* SIGRTMIN + 4 */ 402 { NULL, NULL }, /* SIGRTMIN + 5 */ 403 { NULL, NULL }, /* SIGRTMIN + 6 */ 404 { NULL, NULL }, /* SIGRTMIN + 7 */ 405 { NULL, NULL }, /* SIGRTMIN + 8 */ 406 { NULL, NULL }, /* SIGRTMIN + 9 */ 407 { NULL, NULL }, /* SIGRTMIN + 10 */ 408 { NULL, NULL }, /* SIGRTMIN + 11 */ 409 { NULL, NULL }, /* SIGRTMIN + 12 */ 410 { NULL, NULL }, /* SIGRTMIN + 13 */ 411 { NULL, NULL }, /* SIGRTMIN + 14 */ 412 { NULL, NULL }, /* SIGRTMIN + 15 */ 413 { NULL, NULL }, /* SIGRTMIN + 16 */ 414 { NULL, NULL }, /* SIGRTMIN + 17 */ 415 { NULL, NULL }, /* SIGRTMIN + 18 */ 416 { NULL, NULL }, /* SIGRTMIN + 19 */ 417 { NULL, NULL }, /* SIGRTMIN + 20 */ 418 { NULL, NULL }, /* SIGRTMIN + 21 */ 419 { NULL, NULL }, /* SIGRTMIN + 22 */ 420 { NULL, NULL }, /* SIGRTMIN + 23 */ 421 { NULL, NULL }, /* SIGRTMIN + 24 */ 422 { NULL, NULL }, /* SIGRTMIN + 25 */ 423 { NULL, NULL }, /* SIGRTMIN + 26 */ 424 { NULL, NULL }, /* SIGRTMIN + 27 */ 425 { NULL, NULL }, /* SIGRTMIN + 28 */ 426 { NULL, NULL }, /* SIGRTMIN + 29 */ 427 { NULL, NULL }, /* SIGRTMIN + 30 == SIGRTMAX */ 428 }; 429 373 sigset_t __libc_gSignalPending = {{0,0}}; 374 375 /** Head of the queue of pending signals. 376 * All access to this set is protected by the signal semaphore. 377 */ 378 PSIGQUEUED gpSigQueueHead = NULL; 379 /** Tail of the queue of pending signals. 380 * All access to this set is protected by the signal semaphore. 381 */ 382 PSIGQUEUED gpSigQueueTail = NULL; 430 383 431 384 /** Array of statically allocated queued signals. */ 432 static SIGQUEUED gpaSigQueuedPreAlloced[ 128] =385 static SIGQUEUED gpaSigQueuedPreAlloced[64] = 433 386 { 434 387 { .pNext = &gpaSigQueuedPreAlloced[ 1], .enmHowFree = enmHowFree_PreAllocFree }, /* 0 */ … … 502 455 * All access to this array is protected by the signal semaphore. 503 456 */ 504 static PSIGQUEUED gpSigQueuedFree = &gpaSigQueuedPreAlloced[0]; 457 static PSIGQUEUED gpSigQueuedFree = &gpaSigQueuedPreAlloced[0]; 458 /** Number of structures in the free queue. */ 459 static unsigned gcSigQueuedFree = sizeof(gpaSigQueuedPreAlloced) / sizeof(gpaSigQueuedPreAlloced[0]); 505 460 506 461 … … 508 463 * Internal Functions * 509 464 *******************************************************************************/ 510 static unsigned signalDeliver(int iSignalNo, siginfo_t *pSigInfo, void *pvXcpt); 511 static __LIBC_PTHREAD signalSchedule(int iSignalNo, __LIBC_PTHREAD pThrdCur); 512 static int signalScheduleWorker(__LIBC_PTHREAD pCur, __LIBC_PTHREAD pBest, void *pvParam); 465 static int signalSchedule(__LIBC_PTHREAD pThrd, int iSignalNo, siginfo_t *pSigInfo, unsigned fFlags, PSIGQUEUED pSigQueued); 466 static void signalScheduleSPM(__LIBC_PTHREAD pThrd); 467 static void signalScheduleProcess(__LIBC_PTHREAD pThrd); 468 static void signalScheduleToThread(__LIBC_PTHREAD pThrd, __LIBC_PTHREAD pThrdSig, int iSignalNo, PSIGQUEUED pSig); 469 static __LIBC_PTHREAD signalScheduleThread(int iSignalNo, __LIBC_PTHREAD pThrdCur); 470 static int signalScheduleThreadWorker(__LIBC_PTHREAD pCur, __LIBC_PTHREAD pBest, void *pvParam); 471 static void signalScheduleKickThreads(__LIBC_PTHREAD pThrd); 472 static int signalScheduleKickThreadsWorker(__LIBC_PTHREAD pCur, void *pvParam); 473 static int signalDeliver(__LIBC_PTHREAD pThrd, int iSignalNo, void *pvXcptParams); 474 static void signalTerminate(int iSignalNo) __dead2; 475 static int signalJobStop(int iSignalNo); 476 static int signalJobResume(void); 477 static void signalPokeThread(__LIBC_PTHREAD pThrdPoke); 513 478 static int signalActionWorker(__LIBC_PTHREAD pCur, void *pvParam); 514 479 static unsigned signalTimestamp(void); … … 534 499 FS_SAVE_LOAD(); 535 500 rc = DosCreateMutexSemEx(NULL, &ghmtxSignals, 0, FALSE); 501 if (!rc) 502 { 503 /* 504 * Create the wait semaphore. 505 */ 506 rc = DosCreateEventSemEx(NULL, &ghevWait, 0, 0); 507 if (!rc) 508 { 509 FS_RESTORE(); 510 LIBCLOG_RETURN_INT(0); 511 } 512 else 513 LIBC_ASSERTM_FAILED("DosCreateEventSemEx failed with rc=%d\n", rc); 514 515 DosCloseMutexSemEx(ghmtxSignals); 516 ghmtxSignals = NULLHANDLE; 517 } 518 else 519 LIBC_ASSERTM_FAILED("DosCreateMutexSemEx failed with rc=%d\n", rc); 520 536 521 FS_RESTORE(); 537 if (rc) 538 { 539 LIBC_ASSERTM_FAILED("DosCreateMutexSemEx failed with rc=%d\n", rc); 540 LIBCLOG_RETURN_INT(-1); 541 } 542 543 LIBCLOG_RETURN_INT(0); 522 LIBCLOG_RETURN_INT(-1); 544 523 } 545 524 … … 689 668 * 690 669 * @returns On success a flag mask out of the __LIBC_BSRR_* #defines is returned. 691 * 692 * __LIBC_BSRR_RESTART: Try restart any interrupted system call. 693 * __LIBC_BSRR_INTERRUPT: Go ahead interrupt system call in progress. 694 * 695 * __LIBC_BSRR_CONTINUE: If set execution should be resumed. 696 * __LIBC_BSRR_PASSITON: If set execution should not be resumed but 697 * the signal should be passed on to the system. 698 * 699 * @returns __LIBC_BSRR_ERROR on failure, errno set. 670 * @returns On failure a negative error code (errno.h) is returned. 700 671 * @param iSignalNo Signal to raise. 701 672 * @param pSigInfo Pointer to signal info for this signal. … … 709 680 * @remark This Backend Signal API does NOT require the caller to own the signal semaphore. 710 681 */ 711 unsigned __libc_back_signalRaise(int iSignalNo, siginfo_t *pSigInfo, void *pvXcptOrQueued, unsigned fFlags)682 int __libc_Back_signalRaise(int iSignalNo, siginfo_t *pSigInfo, void *pvXcptOrQueued, unsigned fFlags) 712 683 { 713 684 LIBCLOG_ENTER("iSignalNo=%d pSigInfo=%p pvXcptOrQueued=%p fFlags=%#x\n", 714 685 iSignalNo, (void *)pSigInfo, (void *)pvXcptOrQueued, fFlags); 715 __LIBC_PTHREAD pThrd; 716 __LIBC_PTHREAD pThrdSig = NULL; 717 int rc = __LIBC_BSRR_ERROR; 718 LIBC_ASSERTM(__SIGSET_SIG_VALID(iSignalNo), "Invalid signal %d\n", iSignalNo); 719 720 /* 721 * Assert that we do not own the semaphore upon entry. 722 * This may happen is very special situation, but in general it shouldn't. 686 687 /* 688 * Can't be to careful! 723 689 */ 724 690 LIBC_ASSERTM(!__libc_back_signalSemIsOwner(), "Thread owns the signal semaphore!!! Bad boy!!\n"); 691 if (__SIGSET_SIG_VALID(iSignalNo) || iSignalNo == 0) 692 { 693 LIBC_ASSERTM_FAILED("Invalid signal %d\n", iSignalNo); 694 return -EINVAL; 695 } 725 696 726 697 /* … … 728 699 * There *MUST* be a current thread, if not, we're toast! 729 700 */ 730 pThrd = __libc_threadCurrentNoAuto();701 __LIBC_PTHREAD pThrd = __libc_threadCurrentNoAuto(); 731 702 if (!pThrd) 732 return __LIBC_BSRR_ERROR; 703 { 704 if (fFlags & (__LIBC_BSRF_EXTERNAL | __LIBC_BSRF_HARDWARE)) 705 { 706 LIBC_ASSERTM_FAILED("No thread structure and we cannot safely create one!\n"); 707 return __LIBC_BSRR_PASSITON | (__SIGSET_ISSET(&__libc_gSignalRestartMask, iSignalNo) ? __LIBC_BSRR_RESTART : __LIBC_BSRR_INTERRUPT); 708 } 709 pThrd = __libc_threadCurrent(); 710 if (!pThrd) 711 { 712 LIBC_ASSERTM_FAILED("Failed to get thread structure!\n"); 713 return -ENOMEM; 714 } 715 } 733 716 734 717 /* … … 739 722 if (!pSigInfo->si_timestamp) 740 723 pSigInfo->si_timestamp = signalTimestamp(); 724 if (fFlags & __LIBC_BSRF_QUEUED) 725 pSigInfo->si_flags |= __LIBC_SI_QUEUED; 741 726 if (!pSigInfo->si_pid) 742 727 pSigInfo->si_pid = _sys_pid; … … 744 729 pSigInfo->si_tid = pThrd->tid; 745 730 } 746 747 731 748 732 /* … … 756 740 LIBCLOG_MSG("we're toast!\n"); 757 741 DosWrite(HFILE_STDERR, szMsg, sizeof(szMsg) - 1, &cb); 758 for (;;) 759 DosExit(EXIT_PROCESS, 3); 760 } 761 762 /* 763 * Check if we're ignoring the signal. 742 signalTerminate(iSignalNo); 743 } 744 745 /* 746 * Schedule the signal. 747 */ 748 int rc = signalSchedule(pThrd, iSignalNo, pSigInfo, fFlags, fFlags & __LIBC_BSRF_QUEUED ? pvXcptOrQueued : NULL); 749 if (rc >= 0) 750 { 751 /* 752 * Paranoia scheduling of the process. 753 */ 754 signalScheduleSPM(pThrd); 755 signalScheduleProcess(pThrd); 756 757 /* 758 * Deliver signals pending on this thread. 759 */ 760 int rc = signalDeliver(pThrd, fFlags & __LIBC_BSRF_HARDWARE ? iSignalNo : 0, fFlags & __LIBC_BSRF_QUEUED ? NULL : pvXcptOrQueued); 761 if (rc >= 0 && __SIGSET_ISSET(&__libc_gSignalRestartMask, iSignalNo)) 762 rc = (rc & ~(__LIBC_BSRR_INTERRUPT)) | __LIBC_BSRR_RESTART; 763 } 764 765 return rc; 766 } 767 768 769 /** 770 * Schedules a signal to the appropriate thread or leave it pending on the process. 771 * 772 * @returns 0 on success 773 * @returns Negative error code (errno.h) on failure. 774 * @param pThrd Current thread. 775 * @param iSignalNo Signal number of the signal to be scheduled. 776 * @param pSigInfo Pointer to signal info for this signal. 777 * NULL is allowed. 778 * @param fFlags Flags of the #defines __LIBC_BSRF_* describing how to 779 * deliver the signal. 780 * @param pSigQueued A pointer to locally malloced SIGQUEUED node. NULL is allowed and common. 781 */ 782 static int signalSchedule(__LIBC_PTHREAD pThrd, int iSignalNo, siginfo_t *pSigInfo, unsigned fFlags, PSIGQUEUED pSigQueued) 783 { 784 LIBCLOG_ENTER("pThrd=%p iSignalNo=%d pSigInfo=%p fFlags=%#x pSigQueued=%p\n", 785 (void *)pThrd, iSignalNo, (void *)pSigInfo, fFlags, (void *)pSigQueued); 786 787 LIBC_ASSERTM(__libc_back_signalSemIsOwner(), "Thread doesn't own the signal semaphore!!! Bad boy!!\n"); 788 789 /* 790 * If we're ignoring the signal we just eat it up and return immediately. 764 791 */ 765 792 if ( gaSignalActions[iSignalNo].__sigaction_u.__sa_handler == SIG_IGN … … 768 795 ) 769 796 { 797 /* free any preallocated queued node. */ 798 if (pSigQueued) 799 { 800 pSigQueued->pNext = gpSigQueuedFree; 801 gpSigQueuedFree = pSigQueued->pNext; 802 gcSigQueuedFree++; 803 } 804 805 LIBCLOG_MSG("Ignoring signal %d\n", iSignalNo); 806 LIBCLOG_RETURN_INT(0); 807 } 808 809 810 /* 811 * Try schedule the signal for a thread. 812 */ 813 __LIBC_PTHREAD pThrdSig = NULL; 814 if ( (fFlags & (__LIBC_BSRF_THREAD | __LIBC_BSRF_HARDWARE)) 815 || !(gafSignalProperties[iSignalNo] & SPP_ANYTHRD)) 816 { 770 817 /* 771 * Release the signal sem and log the action.818 * Must be scheduled for the current thread. 772 819 */ 773 __libc_back_signalSemRelease(); 774 LIBCLOG_MSG("Ignoring signal %d\n", iSignalNo); 820 pThrdSig = pThrd; 775 821 } 776 822 else 777 823 { 778 824 /* 779 * Try schedule the signal for a thread. 825 * Schedule for any thread in the process (but obviously 826 * prefering the current thread when ever possible). 780 827 */ 781 if ( (fFlags & __LIBC_BSRF_THREAD) 782 || !(gafSignalProperties[iSignalNo] & SPP_ANYTHRD)) 828 pThrdSig = signalScheduleThread(iSignalNo, pThrd); 829 } 830 831 int rc = 0; 832 if (pThrdSig) 833 { 834 /* 835 * Was it waited for? 836 */ 837 if ( pThrdSig->enmStatus == enmLIBCThreadStatus_sigwait 838 && __SIGSET_ISSET(&pThrdSig->u.SigWait.SigSetWait, iSignalNo)) 783 839 { 784 840 /* 785 * Must be scheduled for the current thread.841 * Wake up a sigwait call. 786 842 */ 787 pThrdSig = pThrd; 843 /** @todo install extra exception handler while accessing this. */ 844 if (pSigInfo) 845 *pThrdSig->u.SigWait.pSigInfo = *pSigInfo; 846 else 847 { 848 bzero(pThrdSig->u.SigWait.pSigInfo, sizeof(*pThrdSig->u.SigWait.pSigInfo)); 849 pThrdSig->u.SigWait.pSigInfo->si_signo = iSignalNo; 850 } 851 pThrdSig->enmStatus = enmLIBCThreadStatus_unknown; 852 if (pThrdSig != pThrd) 853 signalPokeThread(pThrdSig); 854 LIBCLOG_MSG("wokeup sigwait in thread %d on signal %d.\n", pThrdSig->tid, iSignalNo); 788 855 } 789 856 else 790 857 { 791 858 /* 792 * Schedule for any thread in the process (but obviously 793 * prefering the current thread when ever possible). 859 * Not waited for, so just queue it if possible and mark it pending. 794 860 */ 795 pThrdSig = signalSchedule(iSignalNo, pThrd); 796 } 797 798 799 /* 800 * What to do with the signal. 801 */ 802 if (!pThrdSig) 803 { 804 /* 805 * No recepient found, leave it pending somewhere. 806 * 807 * If a queued signal we ignore the ANYTHRD attribute because 808 * that's easier and the specs allow it. 809 */ 810 if ( (gafSignalProperties[iSignalNo] & SPP_ANYTHRD) 811 || (fFlags & __LIBC_BSRF_QUEUED)) 812 { 813 if ( (fFlags & __LIBC_BSRF_QUEUED) 814 || (gafSignalProperties[iSignalNo] & SPP_QUEUED)) 861 if ( (fFlags & __LIBC_BSRF_QUEUED) 862 || (gafSignalProperties[iSignalNo] & SPP_QUEUED)) 863 { 864 /* 865 * Queue the signal. 866 */ 867 if (!pSigQueued) 868 { /* 'allocate' it. */ 869 pSigQueued = gpSigQueuedFree; 870 if (pSigQueued) 871 gpSigQueuedFree = pSigQueued->pNext; 872 } 873 874 /* got a sigqueued node? */ 875 if (pSigQueued) 815 876 { 816 /* 817 * Queue the signal. 818 */ 819 PSIGQUEUED pSigQueued; 820 rc = __LIBC_BSRR_RESTART | __LIBC_BSRR_CONTINUE; 821 if ((fFlags & __LIBC_BSRF_QUEUED) && pvXcptOrQueued) 877 if (pSigInfo) 878 pSigQueued->SigInfo = *pSigInfo; 879 else 880 bzero(pSigQueued, sizeof(*pSigQueued)); 881 pSigQueued->SigInfo.si_signo = iSignalNo; 882 883 /* insert into the queue, give hardware and kill priority (see signalDeliver()). */ 884 if ( (fFlags & __LIBC_BSRF_HARDWARE) 885 || iSignalNo == SIGKILL) 822 886 { 823 pSigQueued = (PSIGQUEUED)pvXcptOrQueued; 824 rc |= __LIBC_BSRR_USED_QUEUED; 825 } 826 else 827 { /* 'allocate' it. */ 828 pSigQueued = gpSigQueuedFree; 829 if (pSigQueued) 830 gpSigQueuedFree = pSigQueued->pNext; 831 } 832 833 /* got a sigqueued node? */ 834 if (pSigQueued) 835 { 836 /* insert into the queue */ 837 if (pSigInfo) 838 pSigQueued->SigInfo = *pSigInfo; 887 pSigQueued->pPrev = NULL; 888 pSigQueued->pNext = pThrdSig->SigQueue.pHead; 889 if (pThrdSig->SigQueue.pHead) 890 pThrdSig->SigQueue.pHead = pThrdSig->SigQueue.pHead->pPrev = pSigQueued; 839 891 else 840 bzero(pSigQueued, sizeof(*pSigQueued)); 841 pSigQueued->SigInfo.si_signo = iSignalNo; 842 pSigQueued->pNext = NULL; 843 pSigQueued->pPrev = gaSignalQueues[iSignalNo].pTail; 844 if (gaSignalQueues[iSignalNo].pTail) 845 gaSignalQueues[iSignalNo].pTail = gaSignalQueues[iSignalNo].pTail->pNext = pSigQueued; 846 else 847 gaSignalQueues[iSignalNo].pTail = gaSignalQueues[iSignalNo].pHead = pSigQueued; 848 __SIGSET_SET(&__libc_gSignalPending, iSignalNo); 849 LIBCLOG_MSG("enqueued signal %d.\n", iSignalNo); 850 } 851 else 852 { /* arg! out of nodes :/ */ 853 errno = EAGAIN; 854 rc = __LIBC_BSRR_ERROR; 855 } 856 } 857 else 858 { 859 /* 860 * Add to the pending signals of this process. 861 */ 862 __SIGSET_SET(&__libc_gSignalPending, iSignalNo); 863 LIBCLOG_MSG("adding %d to pending signals of the current process.\n", iSignalNo); 864 rc = __LIBC_BSRR_RESTART | __LIBC_BSRR_CONTINUE; 865 } 866 } 867 else 868 { 869 /* 870 * Add to the pending signals of this thread. 871 */ 872 __SIGSET_SET(&pThrd->SigSetPending, iSignalNo); 873 LIBCLOG_MSG("adding %d to the pending signals of the current thread.\n", iSignalNo); 874 rc = __LIBC_BSRR_RESTART | __LIBC_BSRR_CONTINUE; 875 } 876 877 /* 878 * Leave the semaphore protection here. 879 */ 880 __libc_back_signalSemRelease(); 881 } 882 else 883 { 884 /* 885 * Make pending? 886 */ 887 /** @todo checkup sigwait and arrival of signal not waited for. */ 888 if ( __SIGSET_ISSET(&pThrdSig->SigSetBlocked, iSignalNo) 889 && ( pThrdSig->enmStatus != enmLIBCThreadStatus_sigwait 890 || !__SIGSET_ISSET(&pThrdSig->u.SigWait.SigSetWait, iSignalNo)) 891 && ( pThrdSig != pThrd 892 || !(fFlags & __LIBC_BSRF_HARDWARE)) 893 ) 894 { 895 /* set signal pending. */ 896 __SIGSET_SET(&pThrd->SigSetPending, iSignalNo); 897 LIBCLOG_MSG("adding %d to the pending signals of thread %d.\n", iSignalNo, pThrdSig->tid); 898 rc = __LIBC_BSRR_RESTART | __LIBC_BSRR_CONTINUE; 899 900 /* 901 * Release the signal thread and leave the semaphore protection. 902 */ 903 if (pThrdSig != pThrd) 904 __libc_threadDereference(pThrdSig); 905 __libc_back_signalSemRelease(); 906 } 907 else 908 { 909 /* 910 * The signal is not blocked or it's waited for. 911 */ 912 if ( pThrdSig == pThrd 913 && ( pThrdSig->enmStatus != enmLIBCThreadStatus_sigwait 914 || __SIGSET_ISSET(&pThrdSig->u.SigWait.SigSetWait, iSignalNo))) 915 { 916 /* 917 * Deliver the signal to the current thread. 918 * This function will release the semaphore for us. 919 */ 920 rc = signalDeliver(iSignalNo, pSigInfo, 921 !(fFlags & __LIBC_BSRF_QUEUED) ? pvXcptOrQueued : NULL); 922 } 923 else 924 { 925 if ( pThrdSig->enmStatus == enmLIBCThreadStatus_sigwait 926 && __SIGSET_ISSET(&pThrdSig->u.SigWait.SigSetWait, iSignalNo)) 927 { 928 /* 929 * Wake up a sigwait call. 930 */ 931 /** @todo install extra exception handler while accessing this. */ 932 if (pSigInfo) 933 *pThrdSig->u.SigWait.pSigInfo = *pSigInfo; 934 else 935 { 936 bzero(pThrdSig->u.SigWait.pSigInfo, sizeof(*pThrdSig->u.SigWait.pSigInfo)); 937 pThrdSig->u.SigWait.pSigInfo->si_signo = iSignalNo; 938 } 939 pThrdSig->enmStatus = enmLIBCThreadStatus_unknown; 940 if (pThrdSig != pThrd) 941 __libc_back_signalPokeThread(pThrdSig->tid); 942 LIBCLOG_MSG("work up sigwait in thread %d on signal %d\n", pThrdSig->tid, iSignalNo); 892 pThrdSig->SigQueue.pHead = pThrdSig->SigQueue.pTail = pSigQueued; 943 893 } 944 894 else 945 895 { 946 /* 947 * Set pending / queue signal with another thread and poke it. 948 */ 949 rc = __LIBC_BSRR_RESTART | __LIBC_BSRR_CONTINUE; 950 if ( (fFlags & __LIBC_BSRF_QUEUED) 951 || (gafSignalProperties[iSignalNo] & SPP_QUEUED)) 952 { 953 /* 954 * Queue the signal. 955 */ 956 PSIGQUEUED pSigQueued; 957 if ((fFlags & __LIBC_BSRF_QUEUED) && pvXcptOrQueued) 958 { 959 pSigQueued = (PSIGQUEUED)pvXcptOrQueued; 960 rc |= __LIBC_BSRR_USED_QUEUED; 961 } 962 else 963 { /* 'allocate' it. */ 964 pSigQueued = gpSigQueuedFree; 965 if (pSigQueued) 966 gpSigQueuedFree = pSigQueued->pNext; 967 } 968 969 /* got a sigqueued node? */ 970 if (pSigQueued) 971 { 972 /* insert into the queue */ 973 if (pSigInfo) 974 pSigQueued->SigInfo = *pSigInfo; 975 else 976 bzero(pSigQueued, sizeof(*pSigQueued)); 977 pSigQueued->SigInfo.si_signo = iSignalNo; 978 pSigQueued->pNext = NULL; 979 pSigQueued->pPrev = pThrdSig->SigQueue.pTail; 980 if (pThrdSig->SigQueue.pTail) 981 pThrdSig->SigQueue.pTail = pThrdSig->SigQueue.pTail->pNext = pSigQueued; 982 else 983 pThrdSig->SigQueue.pTail = pThrdSig->SigQueue.pHead = pSigQueued; 984 LIBCLOG_MSG("enqueued signal %d.\n", iSignalNo); 985 } 986 else 987 { /* arg! out of nodes :/ */ 988 errno = EAGAIN; 989 rc = __LIBC_BSRR_ERROR; 990 } 991 } 992 993 /* 994 * Set pending and poke the thread. 995 */ 996 if (rc != __LIBC_BSRR_ERROR) 997 { 998 __SIGSET_SET(&pThrd->SigSetPending, iSignalNo); 999 __libc_back_signalPokeThread(pThrdSig->tid); 1000 LIBCLOG_MSG("setting %d pending on thread %d's and poking it.\n", pThrdSig->tid, iSignalNo); 1001 } 1002 } /* if/else: sigwait / deliver other thread. */ 1003 1004 /* 1005 * Release the signal thread and leave the semaphore protection. 1006 */ 1007 if (pThrdSig != pThrd) 1008 __libc_threadDereference(pThrdSig); 1009 __libc_back_signalSemRelease(); 1010 } /* if/else: curthread-deliver / sigwait-or-other-thread */ 1011 } /* if/else: blocked-make-thread-pending / deliver */ 1012 } /* if/else: make pending / deliver */ 1013 } /* if/else: ignore / not ignored. */ 896 pSigQueued->pNext = NULL; 897 pSigQueued->pPrev = pThrdSig->SigQueue.pTail; 898 if (pThrdSig->SigQueue.pTail) 899 pThrdSig->SigQueue.pTail = pThrdSig->SigQueue.pTail->pNext = pSigQueued; 900 else 901 pThrdSig->SigQueue.pTail = pThrdSig->SigQueue.pHead = pSigQueued; 902 } 903 LIBCLOG_MSG("enqueued signal %d.\n", iSignalNo); 904 } 905 else 906 { /* arg! out of nodes :/ */ 907 LIBC_ASSERTM_FAILED("Out of queue nodes! iSignalNo=%d\n", iSignalNo); 908 rc = -EAGAIN; 909 } 910 } 911 912 /* 913 * Set pending and poke the thread (if it's not ourself). 914 */ 915 if (!rc) 916 { 917 __SIGSET_SET(&pThrd->SigSetPending, iSignalNo); 918 if (pThrdSig != pThrd) 919 signalPokeThread(pThrdSig); 920 LIBCLOG_MSG("setting %d pending on thread %d's and poking it.\n", pThrdSig->tid, iSignalNo); 921 } 922 } 923 } 924 else 925 { 926 /* 927 * No thread ready for it, leave the signal on process level. 928 * Queue it if required and then mark it pending. 929 */ 930 if ( (fFlags & __LIBC_BSRF_QUEUED) 931 || (gafSignalProperties[iSignalNo] & SPP_QUEUED)) 932 { 933 /* 934 * Queue the signal. 935 */ 936 if (!pSigQueued) 937 { /* 'allocate' it. */ 938 pSigQueued = gpSigQueuedFree; 939 if (pSigQueued) 940 gpSigQueuedFree = pSigQueued->pNext; 941 } 942 943 /* got a sigqueued node? */ 944 if (pSigQueued) 945 { 946 if (pSigInfo) 947 pSigQueued->SigInfo = *pSigInfo; 948 else 949 bzero(pSigQueued, sizeof(*pSigQueued)); 950 pSigQueued->SigInfo.si_signo = iSignalNo; 951 952 /* insert into the queue */ 953 pSigQueued->pNext = NULL; 954 pSigQueued->pPrev = gpSigQueueTail; 955 if (gpSigQueueTail) 956 gpSigQueueTail = gpSigQueueTail->pNext = pSigQueued; 957 else 958 gpSigQueueTail = gpSigQueueHead = pSigQueued; 959 LIBCLOG_MSG("enqueued signal %d.\n", iSignalNo); 960 } 961 else 962 { /* arg! out of nodes :/ */ 963 rc = -EAGAIN; 964 LIBC_ASSERTM_FAILED("Out of queue nodes! iSignalNo=%d\n", iSignalNo); 965 } 966 } 967 968 /* 969 * Add to the pending signals of this process. 970 */ 971 if (rc >= 0) 972 { 973 __SIGSET_SET(&__libc_gSignalPending, iSignalNo); 974 LIBCLOG_MSG("adding %d to pending signals of the current process.\n", iSignalNo); 975 } 976 } 1014 977 1015 978 return rc; … … 1017 980 1018 981 1019 unsigned signalDeliver(int iSignalNo, siginfo_t *pSigInfo, void *pvXcpt) 1020 { 1021 /* 1022 * Assert that we do own the semaphore upon entry. 1023 * This may happen in a very special situation, but in general it shouldn't. 1024 */ 1025 LIBC_ASSERTM(__libc_back_signalSemIsOwner(), "Thread does not own the signal semaphore!!!\n"); 1026 1027 1028 return -1; 982 /** 983 * Checks if we can schedule any of the signals queued on the process in SPM. 984 * 985 * This means discarding (when ignored) or moving signals from pending at 1st 986 * level to 3rd level (thread). signalSchedule() is used to do the actual 987 * thead scheduling of the signals, which means that the caller must check 988 * the current thread for any deliverable signals upon return. 989 * 990 * @param pThrd Current thread. 991 */ 992 static void signalScheduleSPM(__LIBC_PTHREAD pThrd) 993 { 994 LIBCLOG_ENTER("pThrd=%p\n", (void *)pThrd); 995 LIBC_ASSERTM(__libc_back_signalSemIsOwner(), "Thread doesn't own the signal semaphore!!! Bad boy!!\n"); 996 997 /* 998 * Get the mask of pending signals. 999 */ 1000 sigset_t SigSetPending; 1001 int cSignals = __libc_spmSigPending(&SigSetPending); 1002 1003 /* 1004 * Iterate thru the pending signals and see if any of 1005 * them can be delivered. 1006 */ 1007 int iSignalNo = 1; 1008 while (cSignals > 0 && iSignalNo < __SIGSET_MAXSIGNALS) 1009 { 1010 if (__SIGSET_ISSET(&SigSetPending, iSignalNo)) 1011 { 1012 /* 1013 * Let's see if we can ignore it or successfully schedule it to a thread. 1014 */ 1015 __LIBC_PTHREAD pThrdSig = NULL; 1016 if ( gaSignalActions[iSignalNo].__sigaction_u.__sa_handler == SIG_IGN 1017 || ( gaSignalActions[iSignalNo].__sigaction_u.__sa_handler == SIG_DFL 1018 && (gafSignalProperties[iSignalNo] & SPA_MASK) == SPA_IGNORE) 1019 || (pThrdSig = signalScheduleThread(iSignalNo, pThrd))) 1020 { 1021 /* 1022 * Fetch signals of this type. 1023 */ 1024 siginfo_t SigInfo; 1025 while (__libc_spmSigDequeue(iSignalNo, &SigInfo, 1, sizeof(SigInfo)) > 0) 1026 { 1027 int rc = signalSchedule(pThrd, iSignalNo, &SigInfo, 1028 __LIBC_BSRF_EXTERNAL | ((SigInfo.si_flags & __LIBC_SI_QUEUED) ? __LIBC_BSRF_QUEUED : 0), 1029 NULL); 1030 if (rc >= 0) 1031 cSignals--; 1032 else 1033 { 1034 /* Shit! We failed to queue it on a thread. Try put it back in the 1st level queue. */ 1035 LIBCLOG_MSG("failed to schedule signal %d for any thread!\n", iSignalNo); 1036 __libc_spmSigQueue(&SigInfo, _sys_pid, !!(SigInfo.si_flags & __LIBC_SI_QUEUED)); 1037 break; 1038 } 1039 } 1040 } 1041 } 1042 1043 /* next */ 1044 iSignalNo++; 1045 } 1046 LIBCLOG_RETURN_VOID(); 1047 } 1048 1049 1050 /** 1051 * Schedules all signals currently pending on the process (2nd level). 1052 * 1053 * @param pThrd Current Thread. 1054 */ 1055 static void signalScheduleProcess(__LIBC_PTHREAD pThrd) 1056 { 1057 LIBCLOG_ENTER("pThrd=%p\n", (void *)pThrd); 1058 LIBC_ASSERTM(__libc_back_signalSemIsOwner(), "Thread doesn't own the signal semaphore!!! Bad boy!!\n"); 1059 1060 /* 1061 * Process queued signals first (to get a more correct order). 1062 */ 1063 sigset_t SigDone; 1064 __SIGSET_EMPTY(&SigDone); 1065 PSIGQUEUED pSig = gpSigQueueHead; 1066 while (pSig) 1067 { 1068 int iSignalNo = pSig->SigInfo.si_signo; 1069 if (!__SIGSET_ISSET(&SigDone, iSignalNo)) 1070 { 1071 __LIBC_PTHREAD pThrdSig = signalScheduleThread(iSignalNo, pThrd); 1072 if (!pThrdSig) 1073 __SIGSET_SET(&SigDone, iSignalNo); 1074 else 1075 { 1076 /* unlink */ 1077 PSIGQUEUED pSigNext = pSig->pNext; 1078 if (pSig->pPrev) 1079 pSig->pPrev->pNext = pSig->pNext; 1080 else 1081 gpSigQueueHead = pSig->pNext; 1082 if (pSig->pNext) 1083 pSig->pNext->pPrev = pSig->pPrev; 1084 else 1085 gpSigQueueTail = pSig->pPrev; 1086 1087 /* schedule */ 1088 signalScheduleToThread(pThrd, pThrdSig, iSignalNo, pSig); 1089 __SIGSET_CLEAR(&__libc_gSignalPending, iSignalNo); 1090 __libc_threadDereference(pThrdSig); 1091 1092 /* next */ 1093 pSig = pSigNext; 1094 continue; 1095 } 1096 } 1097 1098 /* next */ 1099 pSig = pSig->pNext; 1100 } 1101 1102 /* 1103 * Process pending signals (which was not queued). 1104 */ 1105 int iSignalNo = 0; 1106 while (iSignalNo++ < __SIGSET_MAXSIGNALS) 1107 { 1108 if ( !__SIGSET_ISSET(&SigDone, iSignalNo) 1109 && __SIGSET_ISSET(&__libc_gSignalPending, iSignalNo)) 1110 { 1111 __LIBC_PTHREAD pThrdSig = signalScheduleThread(iSignalNo, pThrd); 1112 if (pThrdSig) 1113 { 1114 signalScheduleToThread(pThrd, pThrdSig, iSignalNo, NULL); 1115 __SIGSET_CLEAR(&__libc_gSignalPending, iSignalNo); 1116 __libc_threadDereference(pThrdSig); 1117 } 1118 } 1119 } 1120 1121 /* 1122 * Now kick all thread with pending signals which can be delivered. 1123 */ 1124 signalScheduleKickThreads(pThrd); 1125 LIBCLOG_RETURN_VOID(); 1126 } 1127 1128 1129 /** 1130 * Schedules a signal to a thread and notifies the thread. 1131 * 1132 * @param pThrd Current thread. 1133 * @param pThrdSig Thread to schedule the signal to. 1134 * @param iSignalNo Signal to schedule. 1135 * @param pSig Signal queue node containing more info about the signal. (Optional) 1136 */ 1137 static void signalScheduleToThread(__LIBC_PTHREAD pThrd, __LIBC_PTHREAD pThrdSig, int iSignalNo, PSIGQUEUED pSig) 1138 { 1139 LIBCLOG_ENTER("pThrd=%p pThrdSig=%p {.tid=%#x} iSignalNo=%d pSig=%p\n", (void *)pThrd, (void *)pThrdSig, pThrdSig->tid, iSignalNo, (void *)pSig); 1140 /* 1141 * If we've got a queue node, queue it. 1142 */ 1143 if (pSig) 1144 { 1145 pSig->pNext = NULL; 1146 pSig->pPrev = pThrdSig->SigQueue.pTail; 1147 if (pThrdSig->SigQueue.pTail) 1148 pThrdSig->SigQueue.pTail->pNext = pSig; 1149 else 1150 pThrdSig->SigQueue.pTail = pThrdSig->SigQueue.pHead = pSig; 1151 } 1152 1153 /* 1154 * In any case, we set the signal pending and poke the thread. 1155 */ 1156 __SIGSET_SET(&pThrd->SigSetPending, iSignalNo); 1157 if (pThrdSig != pThrd) 1158 signalPokeThread(pThrdSig); 1159 LIBCLOG_MSG("setting %d pending on thread %d's and poking it.\n", pThrdSig->tid, iSignalNo); 1160 LIBCLOG_RETURN_VOID(); 1029 1161 } 1030 1162 … … 1032 1164 /** 1033 1165 * Schedules the signal on a suitable thread. 1166 * 1034 1167 * @returns Pointer to a thread structure (referenced). 1035 1168 * @returns NULL if no thread can handle the signal. … … 1037 1170 * @param pThrdCur Pointer to the current thread. 1038 1171 */ 1039 __LIBC_PTHREAD signalSchedule(int iSignalNo, __LIBC_PTHREAD pThrdCur) 1040 { 1172 __LIBC_PTHREAD signalScheduleThread(int iSignalNo, __LIBC_PTHREAD pThrdCur) 1173 { 1174 LIBC_ASSERTM(__libc_back_signalSemIsOwner(), "Thread does not own the signal semaphore!!!\n"); 1175 1176 /* 1177 * Enumerate all thread in the process and figure out which on 1178 * is the best suited to receive the signal. 1179 */ 1041 1180 SIGSCHEDENUMPARAM EnumParam; 1042 __LIBC_PTHREAD pThrdSig;1043 1044 /*1045 * Assert that we do own the semaphore upon entry.1046 * This may happen is very special situation, but in general it shouldn't.1047 */1048 LIBC_ASSERTM(__libc_back_signalSemIsOwner(), "Thread does not own the signal semaphore!!!\n");1049 1050 /*1051 * Enumerate all thread in the process and figure out which is the best suited.1052 */1053 1181 EnumParam.iSignalNo = iSignalNo; 1054 1182 EnumParam.pThrd = pThrdCur; 1055 pThrdSig = __libc_threadLookup2(signalScheduleWorker, &EnumParam); 1056 1057 return NULL; 1183 return __libc_threadLookup2(signalScheduleThreadWorker, &EnumParam); 1058 1184 } 1059 1185 … … 1070 1196 * @param pvParam User parameters (PSIGSCHEDENUMPARAM in our case). 1071 1197 */ 1072 int signalScheduleWorker(__LIBC_PTHREAD pCur, __LIBC_PTHREAD pBest, void *pvParam)1198 static int signalScheduleThreadWorker(__LIBC_PTHREAD pCur, __LIBC_PTHREAD pBest, void *pvParam) 1073 1199 { 1074 1200 PSIGSCHEDENUMPARAM pParam = (PSIGSCHEDENUMPARAM)pvParam; … … 1108 1234 /* ok, it's not blocking it so it's ok to use it. */ 1109 1235 return 1; 1236 } 1237 1238 1239 /** 1240 * Enumerates all the threads in the process and poke the ones 1241 * which have signals that can be process. 1242 * 1243 * @param pThrd Current thread. 1244 */ 1245 static void signalScheduleKickThreads(__LIBC_PTHREAD pThrd) 1246 { 1247 __libc_threadEnum(signalScheduleKickThreadsWorker, (void *)pThrd); 1248 } 1249 1250 1251 /** 1252 * Thread enumeration worker for signalScheduleKickThreads. 1253 * 1254 * It poke threads which have signals that can be delivered. 1255 * 1256 * @returns 0. 1257 * @param pCur The current thread in the enumration. 1258 * @param pvParam This thread. 1259 */ 1260 static int signalScheduleKickThreadsWorker(__LIBC_PTHREAD pCur, void *pvParam) 1261 { 1262 /* 1263 * Skip internal threads. 1264 */ 1265 if (pCur->fInternalThread) 1266 return 0; 1267 1268 /* 1269 * Walk the queued signals and make sure they're pending. 1270 * (Self check.) 1271 */ 1272 PSIGQUEUED pSig = pCur->SigQueue.pHead; 1273 while (pSig) 1274 { 1275 if (!__SIGSET_ISSET(&pCur->SigSetPending, pSig->SigInfo.si_signo)) 1276 { 1277 LIBC_ASSERTM_FAILED("Signal %d is queued but not marked pending on thread %#x!\n", pSig->SigInfo.si_signo, pCur->tid); 1278 __SIGSET_SET(&pCur->SigSetPending, pSig->SigInfo.si_signo); 1279 } 1280 1281 /* next */ 1282 pSig = pSig->pNext; 1283 } 1284 1285 /* 1286 * Skip further processing of threads which have been poked 1287 * or if if it's the current thread 1288 */ 1289 if ( pCur->fSigBeingPoked 1290 || pCur != (__LIBC_PTHREAD)pvParam) 1291 return 0; 1292 1293 /* 1294 * See if there are pending signals that can be delivered. 1295 */ 1296 sigset_t SigSet = pCur->SigSetPending; 1297 __SIGSET_AND(&SigSet, &SigSet, &pCur->SigSetBlocked); 1298 if (!__SIGSET_EMPTY(&SigSet)) 1299 __libc_back_signalPokeThread(pCur->tid); 1300 1301 return 0; 1302 } 1303 1304 1305 /** 1306 * Deliver signals pending on the current thread. 1307 * 1308 * Caller must own the semaphore before calling, this function 1309 * will release the semaphore no matter what happens! 1310 * 1311 * @returns On success a flag mask out of the __LIBC_BSRR_* #defines is returned. 1312 * @returns On failure a negative error code (errno.h) is returned. 1313 * @param pThrd Current thread. 1314 * @param iSignalNo Deliver the first signal of this type no matter if it's 1315 * blocked or not. This is for use with hardware signals only! 1316 * @param pvXcptParams sPointer to exception parameter list is any. 1317 */ 1318 static int signalDeliver(__LIBC_PTHREAD pThrd, int iSignalNo, void *pvXcptParams) 1319 { 1320 LIBCLOG_ENTER("pThrd=%p pvXcptParams=%p\n", (void *)pThrd, pvXcptParams); 1321 int rcRet = __LIBC_BSRR_CONTINUE | __LIBC_BSRR_INTERRUPT; 1322 1323 /* 1324 * Assert that we do own the semaphore upon entry. 1325 */ 1326 LIBC_ASSERTM(__libc_back_signalSemIsOwner(), "Thread does not own the signal semaphore!!!\n"); 1327 1328 for (;;) 1329 { 1330 /* 1331 * Anything pending? 1332 */ 1333 __sigset_t SigDeliver = pThrd->SigSetPending; 1334 __SIGSET_AND(&SigDeliver, &SigDeliver, &pThrd->SigSetBlocked); 1335 if (__SIGSET_ISEMPTY(&SigDeliver)) 1336 break; 1337 1338 /* 1339 * Deliver signals /execute signal default actions in this order: 1340 * 0. Passed in signal (ignores blocking). 1341 * 1. SIGKILL 1342 * 2. Realtime signals. (queued) 1343 * 3. SIGCHLD 1344 * 4. SIGCONT 1345 * 5. Ascending from pending mask. 1346 * 1347 * Note that 0 and 1 may be violating the POSIX specs. 1348 */ 1349 if (!iSignalNo || !__SIGSET_ISSET(&pThrd->SigSetPending, iSignalNo)) 1350 { 1351 iSignalNo = SIGKILL; 1352 if (!__SIGSET_ISSET(&SigDeliver, SIGKILL)) 1353 { 1354 iSignalNo = SIGRTMIN; 1355 while (iSignalNo <= SIGRTMAX && !__SIGSET_ISSET(&SigDeliver, iSignalNo)) 1356 iSignalNo++; 1357 if (iSignalNo > SIGRTMAX) 1358 { 1359 iSignalNo = SIGCHLD; 1360 if (!__SIGSET_ISSET(&SigDeliver, SIGCHLD)) 1361 { 1362 iSignalNo = SIGCONT; 1363 if (!__SIGSET_ISSET(&SigDeliver, SIGCONT)) 1364 { 1365 iSignalNo = 1; 1366 while (iSignalNo < SIGRTMIN && !__SIGSET_ISSET(&SigDeliver, iSignalNo)) 1367 iSignalNo++; 1368 if (iSignalNo >= SIGRTMIN) 1369 { 1370 LIBC_ASSERTM_FAILED("Internal error!!!\n"); 1371 LIBCLOG_RETURN_INT(__LIBC_BSRR_CONTINUE); 1372 } 1373 } 1374 } 1375 } 1376 } 1377 } 1378 1379 /* 1380 * Check if there is a queue element for the signal. 1381 */ 1382 siginfo_t SigInfo = {0}; 1383 PSIGQUEUED pSig = pThrd->SigQueue.pHead; 1384 while (pSig) 1385 { 1386 if (pSig->SigInfo.si_signo == iSignalNo) 1387 { 1388 /* unlink */ 1389 if (pSig->pPrev) 1390 pSig->pPrev->pNext = pSig->pNext; 1391 else 1392 pThrd->SigQueue.pHead = pSig->pNext; 1393 if (pSig->pNext) 1394 pSig->pNext->pPrev = pSig->pPrev; 1395 else 1396 pThrd->SigQueue.pTail = pSig->pPrev; 1397 1398 /* 1399 * Check if more signals of this type so we can update the 1400 * pending mask correctly. 1401 */ 1402 PSIGQUEUED pSigMore = pSig->pNext; 1403 while (pSigMore && pSigMore->SigInfo.si_signo != iSignalNo) 1404 pSigMore = pSigMore->pNext; 1405 if (!pSigMore) 1406 __SIGSET_CLEAR(&pThrd->SigSetPending, iSignalNo); 1407 1408 /* 1409 * Copy the signal to the SigInfo structure on the stack 1410 * and then release the signal queue structure. 1411 */ 1412 SigInfo = pSig->SigInfo; 1413 break; 1414 } 1415 } 1416 1417 /* 1418 * If no queued signal data, then we can simply clear it in the pending mask. 1419 */ 1420 if (!pSig) 1421 { 1422 SigInfo.si_signo = iSignalNo; 1423 __SIGSET_CLEAR(&pThrd->SigSetPending, iSignalNo); 1424 } 1425 1426 1427 /* 1428 * What to do for this signal? 1429 */ 1430 struct sigaction SigAction = gaSignalActions[iSignalNo]; 1431 if ( SigAction.__sigaction_u.__sa_handler == SIG_IGN 1432 || ( SigAction.__sigaction_u.__sa_handler == SIG_DFL 1433 && (gafSignalProperties[iSignalNo] & SPA_MASK) == SPA_IGNORE) 1434 ) 1435 { 1436 /* Ignore the signal. */ 1437 iSignalNo = 0; 1438 continue; 1439 } 1440 1441 if (SigAction.__sigaction_u.__sa_handler == SIG_DFL) 1442 { 1443 /* 1444 * Perform default action. 1445 */ 1446 switch (gafSignalProperties[iSignalNo] & SPA_MASK) 1447 { 1448 /* 1449 * Ignore the signal in one of another way. 1450 */ 1451 case SPA_NEXT: 1452 case SPA_IGNORE: 1453 break; 1454 1455 /* 1456 * Kill process / dump core (no cores for LIBC!). 1457 */ 1458 case SPA_NEXT_KILL: 1459 case SPA_NEXT_CORE: 1460 case SPA_KILL: 1461 case SPA_CORE: 1462 signalTerminate(iSignalNo); 1463 break; 1464 1465 /* 1466 * Stop the current process. 1467 */ 1468 case SPA_STOP: 1469 case SPA_STOPTTY: 1470 signalJobStop(iSignalNo); 1471 break; 1472 1473 /* 1474 * Resume the current process. 1475 */ 1476 case SPA_RESUME: 1477 signalJobResume(); 1478 break; 1479 1480 default: 1481 LIBC_ASSERTM_FAILED("Invalid signal action property! iSignalNo=%d\n", iSignalNo); 1482 break; 1483 } 1484 } 1485 else 1486 { 1487 /* 1488 * Prepare call. 1489 */ 1490 /* reset action in SysV fashion? */ 1491 if ( (SigAction.sa_flags & SA_RESETHAND) 1492 && !(gafSignalProperties[iSignalNo] & SPP_NORESET)) 1493 { 1494 gaSignalActions[iSignalNo].__sigaction_u.__sa_handler = SIG_DFL; 1495 gaSignalActions[iSignalNo].sa_flags &= ~SA_SIGINFO; 1496 SigAction.sa_flags |= SA_NODEFER; 1497 } 1498 1499 /* adjust and apply the signal mask. */ 1500 if ((SigAction.sa_flags & (SA_ACK | SA_NODEFER)) != SA_NODEFER) 1501 __SIGSET_SET(&SigAction.sa_mask, iSignalNo); 1502 if (gafSignalProperties[iSignalNo] & SPP_NOBLOCK) 1503 __SIGSET_CLEAR(&SigAction.sa_mask, iSignalNo); 1504 sigset_t SigSetOld = pThrd->SigSetBlocked; 1505 __SIGSET_OR(&pThrd->SigSetBlocked, &pThrd->SigSetBlocked, &SigAction.sa_mask); 1506 1507 void *pvCtx = NULL; 1508 if (SigAction.sa_flags & SA_SIGINFO) 1509 { 1510 /** @todo Implement x86 signal context. */ 1511 } 1512 1513 /* 1514 * Call the signal handler. 1515 */ 1516 if ( !(SigAction.sa_flags & SA_ONSTACK) 1517 || pThrd->fSigStackActive 1518 || !pThrd->pvSigStack 1519 || !pThrd->cbSigStack) 1520 { 1521 __libc_back_signalSemRelease(); 1522 SigAction.__sigaction_u.__sa_sigaction(iSignalNo, &SigInfo, pvCtx); 1523 } 1524 else 1525 { 1526 /* 1527 * Deliver on an alternative stack. 1528 */ 1529 1530 /* get and save the tib stack pointer entries. */ 1531 PTIB pTib; 1532 PPIB pPib; 1533 FS_VAR(); 1534 FS_SAVE_LOAD(); 1535 DosGetInfoBlocks(&pTib, &pPib); 1536 FS_RESTORE(); 1537 PVOID pvOldStack = pTib->tib_pstack; 1538 PVOID pvOldStackLimit = pTib->tib_pstacklimit; 1539 1540 /* Mark active before we touch the stack so we don't make the same mistake twice... */ 1541 pThrd->fSigStackActive = 1; 1542 /* Setup stack frame for the call. */ 1543 uintptr_t *pStack = (uintptr_t *)((char *)pThrd->pvSigStack + pThrd->cbSigStack - sizeof(uintptr_t)); 1544 *pStack-- = 0; /* where we save esp */ 1545 *pStack-- = (uintptr_t)pvCtx; 1546 *pStack-- = (uintptr_t)&SigInfo; 1547 *pStack-- = iSignalNo; 1548 pTib->tib_pstack = pThrd->pvSigStack; 1549 pTib->tib_pstacklimit = (char *)pThrd->pvSigStack + pThrd->cbSigStack; 1550 1551 /* release, switch and call. */ 1552 __libc_back_signalSemRelease(); 1553 __asm__ __volatile__ ( 1554 "movl %%esp, %0\n\t" 1555 "movl %1, %%esp\n\t" 1556 "call *%2\n\t" 1557 "movl 12(%%esp), %%esp\n\t" 1558 : "=m" (*(uintptr_t *)((char *)pThrd->pvSigStack + pThrd->cbSigStack - sizeof(uintptr_t))) 1559 : "a" (pStack), 1560 "d" (SigAction.__sigaction_u.__sa_sigaction) 1561 : "ecx" ); 1562 1563 /* Restore tib and release the stack. */ 1564 pTib->tib_pstack = pvOldStack; 1565 pTib->tib_pstacklimit = pvOldStackLimit; 1566 pThrd->fSigStackActive = 0; 1567 } 1568 1569 /* 1570 * Handler returned, what to do now? 1571 */ 1572 switch (gafSignalProperties[iSignalNo] & SPR_MASK) 1573 { 1574 /* 1575 * Kill the process. 1576 */ 1577 case SPR_KILL: 1578 signalTerminate(iSignalNo); 1579 break; 1580 1581 /* 1582 * Execution should continue on return, which is our default return. 1583 */ 1584 case SPR_CONTINUE: 1585 break; 1586 1587 default: 1588 LIBC_ASSERTM_FAILED("Invalid signal return action property! iSignalNo=%d\n", iSignalNo); 1589 break; 1590 } 1591 1592 /* 1593 * Re-take the signal semaphore and restore the signal mask. 1594 */ 1595 if (__libc_back_signalSemRequest()) 1596 break; 1597 pThrd->SigSetBlocked = SigSetOld; 1598 } 1599 1600 iSignalNo = 0; 1601 } /* forever */ 1602 1603 LIBCLOG_RETURN_INT(rcRet); 1604 } 1605 1606 1607 /** 1608 * Cause immediate process termination because of the given signal. 1609 * 1610 * @param iSignalNo Signal causing the termination. 1611 */ 1612 static void signalTerminate(int iSignalNo) 1613 { 1614 /** @todo implement process termination by signal properly! */ 1615 /* 1616 * Before we go crazy here, let's release the semaphore. 1617 * 1618 * If possible we'll stay in the must complete section to 1619 * be sure we get to the exit. If not we'll have to mess with 1620 * exception handlers and such now. 1621 */ 1622 //if (__libc_back_signalSemIsOwner()) 1623 // DosReleaseMutexSem(ghmtxSignals); 1624 1625 for (;;) 1626 DosExit(EXIT_THREAD, 127); 1627 } 1628 1629 /** 1630 * Stop the process (job control emulation). 1631 * 1632 * @param iSignalNo Signal causing the stop. 1633 */ 1634 static int signalJobStop(int iSignalNo) 1635 { 1636 /** @todo Job control: tell parent and ensure that thread 1 is frozen and unfrozen. */ 1637 DosWaitEventSem(ghevWait, SEM_INDEFINITE_WAIT); 1638 return 0; 1639 } 1640 1641 /** 1642 * Resume the process (job control emulation). 1643 * 1644 * @param iSignalNo Signal causing the termination. 1645 */ 1646 static int signalJobResume(void) 1647 { 1648 /** @todo Job control: tell parent and ensure that thread 1 is unfrozen. */ 1649 return 0; 1110 1650 } 1111 1651 … … 1189 1729 SigInfo.si_tid = pThrd->tid; 1190 1730 SigInfo.si_timestamp= signalTimestamp(); 1191 1192 rc = __libc_spmSigQueue(&SigInfo, pid, !!(gafSignalProperties[iSignalNo] & SPP_QUEUED)); 1731 if (gafSignalProperties[iSignalNo] & SPP_QUEUED) 1732 SigInfo.si_flags |= __LIBC_SI_QUEUED; 1733 1734 rc = __libc_spmSigQueue(&SigInfo, pid, SigInfo.si_flags & __LIBC_SI_QUEUED); 1193 1735 if (!rc) 1194 1736 { … … 1268 1810 * This is called by the 16-bit thunker. 1269 1811 * 1270 * @param u SignalSignal number - SIG_PFLG_A.1812 * @param uOS2Signal Signal number - SIG_PFLG_A. 1271 1813 * @param uArg LIBC sets this to 0 when the target is a LIBC process. 1272 1814 * If the target is a non-LIBC process it's an EMX signal 1273 1815 * number. 1274 1816 */ 1275 void __libc_back_signalOS2V1Handler32bit(unsigned uSignal, unsigned uArg) 1276 { 1277 /* 1278 * Check the process for pending signals. 1279 */ 1280 //@todo __libc_back_signalPending(); 1817 void __libc_back_signalOS2V1Handler32bit(unsigned uOS2Signal, unsigned uArg) 1818 { 1819 LIBCLOG_ENTER("uOS2Signal=%u uArg=%u\n", uOS2Signal, uArg); 1820 1821 /* 1822 * Can't be to careful! 1823 */ 1824 LIBC_ASSERTM(!__libc_back_signalSemIsOwner(), "Thread owns the signal semaphore!!! That should be impossible...\n"); 1825 1826 /* 1827 * Get the current thread (1st thread, so that should be safe). 1828 */ 1829 __LIBC_PTHREAD pThrd = __libc_threadCurrentNoAuto(); 1830 if (!pThrd) 1831 { 1832 LIBC_ASSERTM_FAILED("Failed to get thread structure!\n"); 1833 LIBCLOG_RETURN_VOID(); 1834 } 1835 1836 /* 1837 * Try schedule signals pending on 1st (SPM) and 2nd level (private). 1838 */ 1839 signalScheduleSPM(pThrd); 1840 signalScheduleProcess(pThrd); 1281 1841 1282 1842 /* … … 1285 1845 if (uArg) 1286 1846 { 1287 unsigned uSignalLIBC= 0;1847 unsigned iSignalNo = 0; 1288 1848 switch (uArg) 1289 1849 { 1290 case EMX_SIGHUP : uSignalLIBC= SIGHUP; break;1291 case EMX_SIGINT : uSignalLIBC= SIGINT; break;1292 case EMX_SIGQUIT : uSignalLIBC= SIGQUIT; break;1293 case EMX_SIGILL : uSignalLIBC= SIGILL; break;1294 case EMX_SIGTRAP : uSignalLIBC= SIGTRAP; break;1295 case EMX_SIGABRT : uSignalLIBC= SIGABRT; break;1296 case EMX_SIGEMT : uSignalLIBC= SIGEMT; break;1297 case EMX_SIGFPE : uSignalLIBC= SIGFPE; break;1298 case EMX_SIGKILL : uSignalLIBC= SIGKILL; break;1299 case EMX_SIGBUS : uSignalLIBC= SIGBUS; break;1300 case EMX_SIGSEGV : uSignalLIBC= SIGSEGV; break;1301 case EMX_SIGSYS : uSignalLIBC= SIGSYS; break;1302 case EMX_SIGPIPE : uSignalLIBC= SIGPIPE; break;1303 case EMX_SIGALRM : uSignalLIBC= SIGALRM; break;1304 case EMX_SIGTERM : uSignalLIBC= SIGTERM; break;1305 case EMX_SIGUSR1 : uSignalLIBC= SIGUSR1; break;1306 case EMX_SIGUSR2 : uSignalLIBC= SIGUSR2; break;1307 case EMX_SIGCHLD : uSignalLIBC= SIGCHLD; break;1308 case EMX_SIGBREAK: uSignalLIBC= SIGBREAK; break;1309 case EMX_SIGWINCH: uSignalLIBC= SIGWINCH; break;1310 } 1311 if ( uSignalLIBC)1850 case EMX_SIGHUP : iSignalNo = SIGHUP; break; 1851 case EMX_SIGINT : iSignalNo = SIGINT; break; 1852 case EMX_SIGQUIT : iSignalNo = SIGQUIT; break; 1853 case EMX_SIGILL : iSignalNo = SIGILL; break; 1854 case EMX_SIGTRAP : iSignalNo = SIGTRAP; break; 1855 case EMX_SIGABRT : iSignalNo = SIGABRT; break; 1856 case EMX_SIGEMT : iSignalNo = SIGEMT; break; 1857 case EMX_SIGFPE : iSignalNo = SIGFPE; break; 1858 case EMX_SIGKILL : iSignalNo = SIGKILL; break; 1859 case EMX_SIGBUS : iSignalNo = SIGBUS; break; 1860 case EMX_SIGSEGV : iSignalNo = SIGSEGV; break; 1861 case EMX_SIGSYS : iSignalNo = SIGSYS; break; 1862 case EMX_SIGPIPE : iSignalNo = SIGPIPE; break; 1863 case EMX_SIGALRM : iSignalNo = SIGALRM; break; 1864 case EMX_SIGTERM : iSignalNo = SIGTERM; break; 1865 case EMX_SIGUSR1 : iSignalNo = SIGUSR1; break; 1866 case EMX_SIGUSR2 : iSignalNo = SIGUSR2; break; 1867 case EMX_SIGCHLD : iSignalNo = SIGCHLD; break; 1868 case EMX_SIGBREAK: iSignalNo = SIGBREAK; break; 1869 case EMX_SIGWINCH: iSignalNo = SIGWINCH; break; 1870 } 1871 if (iSignalNo) 1312 1872 { 1313 1873 /* 1314 * Ok, raise it. 1315 * Don't know how we should handle the exit code here, so we'll 1316 * ignore it for now. 1874 * Shcedule the signal, ignore return code. 1317 1875 */ 1318 __libc_back_signalRaise(uSignalLIBC, NULL, NULL, __LIBC_BSRF_EXTERNAL);1876 signalSchedule(pThrd, iSignalNo, NULL, __LIBC_BSRF_EXTERNAL, NULL); 1319 1877 } 1320 1878 } … … 1323 1881 * Acknowledge the signal. 1324 1882 */ 1325 DosSetSigHandler(NULL, NULL, NULL, SIGA_ACKNOWLEDGE, uSignal); 1883 DosSetSigHandler(NULL, NULL, NULL, SIGA_ACKNOWLEDGE, uOS2Signal); 1884 1885 /* 1886 * Deliver signals. 1887 */ 1888 signalDeliver(pThrd, 0, NULL); 1889 LIBCLOG_RETURN_VOID(); 1326 1890 } 1327 1891 … … 1335 1899 void __libc_back_signalPokeThread(int tid) 1336 1900 { 1337 /*1338 * Assert that we do not own the semaphore upon entry.1339 * This may happen is very special situation, but in general it shouldn't.1340 */1341 1901 LIBC_ASSERTM(__libc_back_signalSemIsOwner(), "Thread must own signal sem!\n"); 1342 1902 … … 1345 1905 */ 1346 1906 __LIBC_PTHREAD pThrdPoke = __libc_threadLookup(tid); 1347 if (!pThrdPoke) 1348 return; 1907 if (pThrdPoke) 1908 { 1909 signalPokeThread(pThrdPoke); 1910 __libc_threadDereference(pThrdPoke); 1911 } 1912 } 1913 1914 1915 /** 1916 * Pokes a thread in the current process, forcing it to 1917 * evaluate pending signals. 1918 * 1919 * @param pThrdPoke Thread to poke. 1920 */ 1921 static void signalPokeThread(__LIBC_PTHREAD pThrdPoke) 1922 { 1923 LIBC_ASSERTM(__libc_back_signalSemIsOwner(), "Thread must own signal sem!\n"); 1349 1924 1350 1925 /* … … 1354 1929 { 1355 1930 __atomic_xchg(&pThrdPoke->fSigBeingPoked, 1); 1356 int rc = DosKillThread( tid);1931 int rc = DosKillThread(pThrdPoke->tid); 1357 1932 if (rc) 1358 LIBC_ASSERTM_FAILED("DosKillThread(%d) -> rc=%d\n", tid, rc); 1359 } 1360 1361 /* 1362 * Release the thread. 1363 */ 1364 __libc_threadDereference(pThrdPoke); 1365 } 1366 1367 1368 /** @todo implement this. */ 1933 LIBC_ASSERTM_FAILED("DosKillThread(%d) -> rc=%d\n", pThrdPoke->tid, rc); 1934 } 1935 } 1936 1937 1938 1939 /** 1940 * Thread was poked, deliver signals for this thread. 1941 */ 1369 1942 int __libc_back_signalRaisePoked(void *pvXcptParams, int tidPoker) 1370 1943 { 1371 /*1372 * Assert that we do not own the semaphore upon entry.1373 */1374 1944 LIBC_ASSERTM(!__libc_back_signalSemIsOwner(), "Thread owns the signal semaphore!!! Bad boy!!\n"); 1375 1945 … … 1383 1953 * Take signal semaphore. 1384 1954 */ 1385 int SavedErrno = errno;1386 1955 int rc = __libc_back_signalSemRequest(); 1387 1956 if (!rc) … … 1390 1959 { 1391 1960 /* 1392 * Clear the indicator .1961 * Clear the indicator and deliver signals. 1393 1962 */ 1394 1963 __atomic_xchg(&pThrd->fSigBeingPoked, 0); 1395 1396 /*1397 * Check for pending signals.1398 */1399 1400 __libc_back_signalSemRelease(); 1401 }1402 else1403 __libc_back_signalSemRelease();1404 }1405 errno = SavedErrno;1964 rc = signalDeliver(pThrd, 0, pvXcptParams); 1965 if (rc < 0) 1966 rc = __LIBC_BSRR_CONTINUE | __LIBC_BSRR_INTERRUPT; 1967 return rc; 1968 } 1969 1970 /* 1971 * We weren't being poked. 1972 */ 1973 __libc_back_signalSemRelease(); 1974 } 1406 1975 } 1407 1976 else 1408 1977 LIBC_ASSERTM_FAILED("No thread structure! This is really impossible!\n"); 1409 1978 1410 return __LIBC_BSRR_ERROR;1979 return -EINVAL; 1411 1980 } 1412 1981 -
Property cvs2svn:cvs-rev
changed from
Note:
See TracChangeset
for help on using the changeset viewer.