Changeset 1615 for trunk/src


Ignore:
Timestamp:
Nov 6, 2004, 9:35:32 AM (21 years ago)
Author:
bird
Message:

signals are finally getting somewhere...

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 to 1.12
    r1614 r1615  
    109109
    110110
     111/** The maximum number of signals a process can have pending on other processes concurrently. */
     112#define __LIBC_SPM_SIGNALS_MAX_SENT 48
     113
    111114/**
    112115 * Signal (queued).
     
    118121    /** Pointer to the next signal. */
    119122    struct __libc_SPMSignal    *pNext;
     123    /** Sender process.
     124     * This is used to decrement the cSigsSent count of the sender. */
     125    pid_t                       pidSender;
     126
    120127    /** Signal info. */
    121128    siginfo_t                   Info;
     
    277284     * For signals which aren't queable only one signal can be queued.
    278285     */
    279     __LIBC_PSPMSIGNAL           pSigHead;
    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;
    284291
    285292    /** Reserved pool pointer field with default value 0. */
     
    653660
    654661/**
    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 */
     669int     __libc_spmSigPending(sigset_t *pSigSet);
     670
     671/**
     672 * De-queues one or more pending signals of a specific type.
     673 *
    656674 * @returns Number of de-queued signals on success.
    657675 * @returns Negative error code (errno.h) on failure.
     676 * @param   iSignalNo   Signal type to dequeue.
    658677 * @param   paSignals   Where to store the signals.
    659678 * @param   cSignals    Size of the signal array.
    660679 * @param   cbSignal    Size of one signal entry.
    661680 */
    662 int     __libc_spmSigDequeue(siginfo_t *paSignals, unsigned cSignals, size_t cbSignal);
     681int     __libc_spmSigDequeue(int iSignalNo, siginfo_t *paSignals, unsigned cSignals, size_t cbSignal);
    663682
    664683
  • trunk/src/emx/include/InnoTekLIBC/signals.h

    • Property cvs2svn:cvs-rev changed from 1.2 to 1.3
    r1614 r1615  
    3232*******************************************************************************/
    3333/** @defgroup __libc_back_signalRaise_return    __libc_back_signalRaise() returns.
     34 * These are only valid for positive return values.
    3435 * @{ */
    3536/** Try restart any interrupted system call. */
     
    4445/** If set the passed in SIGQUEUED structure was used. */
    4546#define __LIBC_BSRR_USED_QUEUED 0x40
    46 /** Failure. */
    47 #define __LIBC_BSRR_ERROR       0xffffff22
    4847/** @} */
    4948
     
    9493int         __libc_back_signalSuspend(void);
    9594int         __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);
    9995int         __libc_back_signalSendPidOther(pid_t pid, int iSignalNo);
    100 int         __libc_back_signalSendPGrp(pid_t pgrp, int iSignalNo);
    10196int         __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);
    10397int         __libc_back_signalRaisePoked(void *pvXcptParams, int tidPoker);
    10498void        __libc_back_signalOS2V1Handler16bit(unsigned short uSignal, unsigned short uArg);
    10599void        __libc_back_signalOS2V1Handler32bit(unsigned uSignal, unsigned uArg);
    106100
     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 */
     118int __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 */
     130int     __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 */
     143int     __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 */
     154int     __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 */
     167int     __libc_Back_signalVerifyPGrp(pid_t pgid);
     168
     169
    107170__END_DECLS
    108171
  • trunk/src/emx/include/sys/signal.h

    • Property cvs2svn:cvs-rev changed from 1.6 to 1.7
    r1614 r1615  
    147147/** Take signal on a registerd stack_t. */
    148148#define SA_ONSTACK          0x00000001
    149 /** Restart system call on signal return. Not implemented on OS/2. */
     149/** Restart system call on signal return. */
    150150#define SA_RESTART          0x00000002
    151151/** Reset signal handler to SIG_DFL when deliving the signal. */
     
    395395    /** Timestamp when the signal was generated - LIBC extension. */
    396396    unsigned        si_timestamp;
     397    /** Flags - LIBC extension. __LIBC_SI_* */
     398    unsigned        si_flags;
    397399    /** Process sending the signal. */
    398400    __pid_t         si_pid;
     
    412414    int             si_fd;
    413415    /** Reserve a little bit for future usage. */
    414     unsigned        auReserved[4];
     416    unsigned        auReserved[3];
    415417} 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
    416426#endif
    417427
  • trunk/src/emx/src/lib/libc.def

    • Property cvs2svn:cvs-rev changed from 1.72 to 1.73
    r1614 r1615  
    12301230    "__std_sigwait" @1252
    12311231    "__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
  • trunk/src/emx/src/lib/process/kill.c

    • Property cvs2svn:cvs-rev changed from 1.3 to 1.4
    r1614 r1615  
    7575     */
    7676    if (pid > 0)
    77         rc = __libc_back_signalVerifyPid(pid);
     77        rc = __libc_Back_signalVerifyPid(pid);
    7878    else /* (pid <= 0) */
    79         rc = __libc_back_signalVerifyPGrp(-pid);
     79        rc = __libc_Back_signalVerifyPGrp(-pid);
    8080    if (!rc)
    8181    {
     
    9090         */
    9191        if (pid > 0)
    92             rc = __libc_back_signalSendPid(pid, iSignalNo);
     92            rc = __libc_Back_signalSendPid(pid, iSignalNo);
    9393        else
    94             rc = __libc_back_signalSendPGrp(-pid, iSignalNo);
     94            rc = __libc_Back_signalSendPGrp(-pid, iSignalNo);
    9595        if (!rc)
    9696            LIBCLOG_RETURN_INT(0);
  • trunk/src/emx/src/lib/sys/b_signalSendPGrp.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1614 r1615  
    5252 * @param   iSignalNo   Signal to send to all the processes in the group.
    5353 */
    54 int         __libc_back_signalSendPGrp(pid_t pgrp, int iSignalNo)
     54int         __libc_Back_signalSendPGrp(pid_t pgrp, int iSignalNo)
    5555{
    5656    LIBC_ASSERTM_FAILED("__libc_back_signalSendPGrp is not implemented\n");
  • trunk/src/emx/src/lib/sys/b_signalSendPid.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1614 r1615  
    5353 * @remark  This Backend Signal API does NOT require the caller to own the signal semaphore.
    5454 */
    55 int     __libc_back_signalSendPid(pid_t pid, int iSignalNo)
     55int     __libc_Back_signalSendPid(pid_t pid, int iSignalNo)
    5656{
    5757    LIBCLOG_ENTER("pid=%d iSignalNo=%d\n", pid, iSignalNo);
     
    5959
    6060    /*
    61      * Certain assumption are made.
     61     * Validate input.
    6262     */
    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    }
    6573
    6674    /*
     
    7179    else
    7280    {
    73         int old_errno =
    74         rc = __libc_back_signalRaise(iSignalNo, NULL, NULL, 0);
     81        rc = __libc_Back_signalRaise(iSignalNo, NULL, NULL, 0);
    7582        if (rc > 0)
    7683            rc = 0;
  • trunk/src/emx/src/lib/sys/b_signalVerifyPGrp.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1614 r1615  
    5151 * @remark  This Backend Signal API does NOT require the caller to own the signal semaphore.
    5252 */
    53 int     __libc_back_signalVerifyPGrp(pid_t pgid)
     53int     __libc_Back_signalVerifyPGrp(pid_t pgid)
    5454{
    5555    LIBCLOG_ENTER("pgid=%d\n", pgid);
  • trunk/src/emx/src/lib/sys/b_signalVerifyPid.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1614 r1615  
    5151 * @remark  This Backend Signal API does NOT require the caller to own the signal semaphore.
    5252 */
    53 int     __libc_back_signalVerifyPid(pid_t pid)
     53int     __libc_Back_signalVerifyPid(pid_t pid)
    5454{
    5555    LIBCLOG_ENTER("pid=%d\n", pid);
  • trunk/src/emx/src/lib/sys/exceptions.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1614 r1615  
    7777    __asm__ ("cld");                    /* usual paranoia.  */
    7878    siginfo_t   SigInfo = {0};
    79     int         rc;                     /* return from __libc_back_signalRaise() */
     79    int         rc;                     /* return from __libc_Back_signalRaise() */
    8080
    8181    if (pXcptRepRec->fHandlerFlags & (EH_UNWINDING | EH_EXIT_UNWIND))
     
    116116                            case XCPT_SIGNAL_KILLPROC:  SigInfo.si_signo = SIGTERM; break;
    117117                        }
    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);
    119119                        break;
    120120                }
     
    156156            SigInfo.si_addr = (void*)pXcptRepRec->ExceptionInfo[1]; /* accessed memory address */
    157157            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);
    159159            break;
    160160
     
    166166            SigInfo.si_code  = BUS_ADRALN;
    167167            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);
    169169            break;
    170170
     
    176176            SigInfo.si_code  = FPE_INTDIV;
    177177            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);
    179179            break;
    180180
     
    183183            SigInfo.si_code  = FPE_INTOVF;
    184184            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);
    186186            break;
    187187
     
    190190            SigInfo.si_code  = FPE_FLTDIV;
    191191            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);
    193193            break;
    194194
     
    197197            SigInfo.si_code  = FPE_FLTOVF;
    198198            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);
    200200            break;
    201201
     
    204204            SigInfo.si_code  = FPE_FLTUND;
    205205            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);
    207207            break;
    208208
     
    211211            SigInfo.si_code  = FPE_FLTINV; /* ??? */
    212212            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);
    214214            break;
    215215
     
    218218            SigInfo.si_code  = FPE_FLTRES;
    219219            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);
    221221            break;
    222222
     
    225225            SigInfo.si_code  = FPE_FLTINV;
    226226            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);
    228228            break;
    229229
     
    232232            SigInfo.si_code  = FPE_FLTINV; /* ??? */
    233233            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);
    235235            break;
    236236
     
    239239            SigInfo.si_code  = FPE_FLTSUB;
    240240            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);
    242242            break;
    243243
     
    250250            SigInfo.si_code  = ILL_ILLOPC; /* this could be any ILL_ILLO* */
    251251            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);
    253253            break;
    254254
     
    257257            SigInfo.si_code  = ILL_ILLADR; /* ?????? */
    258258            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);
    260260            break;
    261261
     
    264264            SigInfo.si_code  = ILL_PRVOPC; /* this could be ILL_PRVREG too. */
    265265            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);
    267267            break;
    268268
     
    274274            SigInfo.si_code  = TRAP_TRACE; /* (?) */
    275275            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);
    277277            break;
    278278        case XCPT_BREAKPOINT:
     
    280280            SigInfo.si_code  = TRAP_BRKPT;
    281281            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);
    283283            break;
    284284
     
    291291            /*
    292292             * This exception is special. We use it to poke threads with pending signals.
    293              * __libc_back_signalRaisePoked() will retest the flag from within the semaphore
     293             * __libc_Back_signalRaisePoked() will retest the flag from within the semaphore
    294294             * protection and returns __LIBC_BSRR_ERROR if it fails.
    295295             */
     
    297297            if (    !pThrd
    298298                ||  !pThrd->fSigBeingPoked
    299                 ||  (rc = __libc_back_signalRaisePoked(&pXcptRepRec, pXcptRepRec->ExceptionInfo[0])) == __LIBC_BSRR_ERROR)
     299                ||  (rc = __libc_back_signalRaisePoked(&pXcptRepRec, pXcptRepRec->ExceptionInfo[0])) < 0)
    300300            {
    301301                #if 0 /** bird: no so sure about this. */
     
    329329    }
    330330
    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;
    332332}
    333333
  • trunk/src/emx/src/lib/sys/sharedpm.c

    • Property cvs2svn:cvs-rev changed from 1.12 to 1.13
    r1614 r1615  
    895895     * This is mostly because we wanna crash before we take the sem.
    896896     */
    897 #ifdef SIGRTMAX                         /* just make it build. */
    898897    if (pSignal->si_signo <= 0 || pSignal->si_signo > SIGRTMAX)
    899898    {
     
    901900        LIBCLOG_RETURN_INT(-EINVAL);
    902901    }
    903 #endif
    904902    if (pSignal->auReserved[(sizeof(pSignal->auReserved) / sizeof(pSignal->auReserved[0])) - 1])
    905903    {
     
    939937             * Check that we're not exceeding any per process or system limits.
    940938             */
    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)
    945941                || pSignal->si_signo == SIGCHLD)
    946942            {
     
    968964                        pSig->cb = sizeof(*pSig);
    969965                }
     966                /*
     967                 * Copy the data and insert it into the queue.
     968                 */
    970969                if (pSig)
    971970                {
    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++;
    979989                    gpSPMHdr->cSigActive++;
    980                     rc = 0;
    981990                }
    982991                else
     
    988997            else
    989998            {
    990                 LIBCLOG_MSG("Limit reached: cSigActive=%d cSigMaxActive=%d cSigsQueued=%d (max 48)\n",
    991                             gpSPMHdr->cSigActive, gpSPMHdr->cSigMaxActive, pProcess->cSigsQueued);
     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);
    9921001                rc = -EAGAIN;
    9931002            }
     
    10081017
    10091018/**
    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.
    10121023 * @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 */
     1026int     __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);
    10301035
    10311036    /*
     
    10401045     * De-queue signals one-by-one.
    10411046     */
    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 */
     1070int     __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
    10441110        /*
    10451111         * Copy it.
    10461112         */
    1047         __LIBC_PSPMSIGNAL pSig = gpSPMSelf->pSigHead;
    10481113        if (pSig->cb >= sizeof(siginfo_t))
    10491114            *paSignals = pSig->Info;
     
    10541119         * Unlink it and free it.
    10551120         */
    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;
    10591138        if (gpSPMHdr->cSigFree < 32)
    10601139        {
     
    10661145            spmFree(pSig);
    10671146
    1068         /* next */
     1147        /*
     1148         * Next.
     1149         */
     1150        pSig = pSigNext;
     1151        paSignals = (siginfo_t *)((char *)paSignals + cbSignal);
    10691152        rc++;
    1070         paSignals = (siginfo_t *)((char *)paSignals + cbSignal);
    10711153    }
    10721154
     
    14101492        rc = DosGetNamedSharedMem(&pv, (PCSZ)SPM_MEMORY_NAME, PAG_READ | PAG_WRITE);
    14111493        if (!rc)
     1494        {
    14121495            gpSPMHdr = (__LIBC_PSPMHEADER)pv;
     1496            if (!gpSPMHdr->cSigMaxActive)
     1497                gpSPMHdr->cSigMaxActive = 1024;
     1498        }
    14131499        else
    14141500        {
  • trunk/src/emx/src/lib/sys/signals.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1614 r1615  
    3030 * LIBC fully implements the posix signal handling.
    3131 *
    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 *
    3861 *
    3962 */
     
    6992
    7093/** @defgroup libc_back_signals_properties  Signal Properties
     94 * The return actions are ordered by precendece.
    7195 * @{ */
     96/** Return Action: Terminate. */
     97#define SPR_KILL        0x0000
    7298/** 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
    80100/** Return Action Mask */
    81 #define SPR_MASK        0x0003
     101#define SPR_MASK        0x0001
    82102
    83103/** Action: Ignore the signal. */
     
    110130/** Property: This signal can be queued. */
    111131#define SPP_QUEUED      0x0800
     132/** Property: Signal action cannot be automatically reset in SysV fashion. */
     133#define SPP_NORESET     0x1000
    112134/** @} */
    113135
     
    166188
    167189
    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 SignalQueue
    173 {
    174     /** Pointer to the head. */
    175     PSIGQUEUED  pHead;
    176     /** Pointer to the tail. */
    177     PSIGQUEUED  pTail;
    178 } SIGQUEUE, *PSIGQUEUE;
    179 
    180 
    181190/** Thread enumeration state data.
    182  * Used by signalSchedule() when enumerating threads.
     191 * Used by signalScheduleThread() when enumerating threads.
    183192 */
    184193typedef struct SigSchedEnumParam
     
    205214static HMTX             ghmtxSignals;
    206215
     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 */
     222static HEV              ghevWait;
     223
    207224/** Signal Properties.
    208225 * Describes the default actions of a signal.
     
    211228{
    212229    /* 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) */
    246263    /* 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 */
    278295};
    279296
     
    354371 * All access to this set is protected by the signal semaphore.
    355372 */
    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 
     373sigset_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 */
     378PSIGQUEUED          gpSigQueueHead = NULL;
     379/** Tail of the queue of pending signals.
     380 * All access to this set is protected by the signal semaphore.
     381 */
     382PSIGQUEUED          gpSigQueueTail = NULL;
    430383
    431384/** Array of statically allocated queued signals. */
    432 static SIGQUEUED    gpaSigQueuedPreAlloced[128] =
     385static SIGQUEUED    gpaSigQueuedPreAlloced[64] =
    433386{
    434387    { .pNext = &gpaSigQueuedPreAlloced[ 1], .enmHowFree = enmHowFree_PreAllocFree },    /* 0 */
     
    502455 * All access to this array is protected by the signal semaphore.
    503456 */
    504 static PSIGQUEUED    gpSigQueuedFree = &gpaSigQueuedPreAlloced[0];
     457static PSIGQUEUED   gpSigQueuedFree = &gpaSigQueuedPreAlloced[0];
     458/** Number of structures in the free queue. */
     459static unsigned     gcSigQueuedFree = sizeof(gpaSigQueuedPreAlloced) / sizeof(gpaSigQueuedPreAlloced[0]);
    505460
    506461
     
    508463*   Internal Functions                                                         *
    509464*******************************************************************************/
    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);
     465static int              signalSchedule(__LIBC_PTHREAD pThrd, int iSignalNo, siginfo_t *pSigInfo, unsigned fFlags, PSIGQUEUED pSigQueued);
     466static void             signalScheduleSPM(__LIBC_PTHREAD pThrd);
     467static void             signalScheduleProcess(__LIBC_PTHREAD pThrd);
     468static void             signalScheduleToThread(__LIBC_PTHREAD pThrd, __LIBC_PTHREAD pThrdSig, int iSignalNo, PSIGQUEUED pSig);
     469static __LIBC_PTHREAD   signalScheduleThread(int iSignalNo, __LIBC_PTHREAD pThrdCur);
     470static int              signalScheduleThreadWorker(__LIBC_PTHREAD pCur, __LIBC_PTHREAD pBest, void *pvParam);
     471static void             signalScheduleKickThreads(__LIBC_PTHREAD pThrd);
     472static int              signalScheduleKickThreadsWorker(__LIBC_PTHREAD pCur, void *pvParam);
     473static int              signalDeliver(__LIBC_PTHREAD pThrd, int iSignalNo, void *pvXcptParams);
     474static void             signalTerminate(int iSignalNo) __dead2;
     475static int              signalJobStop(int iSignalNo);
     476static int              signalJobResume(void);
     477static void             signalPokeThread(__LIBC_PTHREAD pThrdPoke);
    513478static int              signalActionWorker(__LIBC_PTHREAD pCur, void *pvParam);
    514479static unsigned         signalTimestamp(void);
     
    534499    FS_SAVE_LOAD();
    535500    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
    536521    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);
    544523}
    545524
     
    689668 *
    690669 * @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.
    700671 * @param   iSignalNo           Signal to raise.
    701672 * @param   pSigInfo            Pointer to signal info for this signal.
     
    709680 * @remark  This Backend Signal API does NOT require the caller to own the signal semaphore.
    710681 */
    711 unsigned __libc_back_signalRaise(int iSignalNo, siginfo_t *pSigInfo, void *pvXcptOrQueued, unsigned fFlags)
     682int __libc_Back_signalRaise(int iSignalNo, siginfo_t *pSigInfo, void *pvXcptOrQueued, unsigned fFlags)
    712683{
    713684    LIBCLOG_ENTER("iSignalNo=%d pSigInfo=%p pvXcptOrQueued=%p fFlags=%#x\n",
    714685                  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!
    723689     */
    724690    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    }
    725696
    726697    /*
     
    728699     * There *MUST* be a current thread, if not, we're toast!
    729700     */
    730     pThrd = __libc_threadCurrentNoAuto();
     701    __LIBC_PTHREAD  pThrd = __libc_threadCurrentNoAuto();
    731702    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    }
    733716
    734717    /*
     
    739722        if (!pSigInfo->si_timestamp)
    740723            pSigInfo->si_timestamp = signalTimestamp();
     724        if (fFlags & __LIBC_BSRF_QUEUED)
     725            pSigInfo->si_flags |= __LIBC_SI_QUEUED;
    741726        if (!pSigInfo->si_pid)
    742727            pSigInfo->si_pid = _sys_pid;
     
    744729            pSigInfo->si_tid = pThrd->tid;
    745730    }
    746 
    747731
    748732    /*
     
    756740        LIBCLOG_MSG("we're toast!\n");
    757741        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 */
     782static 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.
    764791     */
    765792    if (    gaSignalActions[iSignalNo].__sigaction_u.__sa_handler == SIG_IGN
     
    768795        )
    769796    {
     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    {
    770817        /*
    771          * Release the signal sem and log the action.
     818         * Must be scheduled for the current thread.
    772819         */
    773         __libc_back_signalSemRelease();
    774         LIBCLOG_MSG("Ignoring signal %d\n", iSignalNo);
     820        pThrdSig = pThrd;
    775821    }
    776822    else
    777823    {
    778824        /*
    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).
    780827         */
    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))
    783839        {
    784840            /*
    785              * Must be scheduled for the current thread.
     841             * Wake up a sigwait call.
    786842             */
    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);
    788855        }
    789856        else
    790857        {
    791858            /*
    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.
    794860             */
    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)
    815876                {
    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)
    822886                    {
    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;
    839891                        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;
    943893                    }
    944894                    else
    945895                    {
    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    }
    1014977
    1015978    return rc;
     
    1017980
    1018981
    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 */
     992static 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 */
     1055static 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 */
     1137static 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();
    10291161}
    10301162
     
    10321164/**
    10331165 * Schedules the signal on a suitable thread.
     1166 *
    10341167 * @returns Pointer to a thread structure (referenced).
    10351168 * @returns NULL if no thread can handle the signal.
     
    10371170 * @param   pThrdCur    Pointer to the current thread.
    10381171 */
    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     */
    10411180    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      */
    10531181    EnumParam.iSignalNo = iSignalNo;
    10541182    EnumParam.pThrd     = pThrdCur;
    1055     pThrdSig = __libc_threadLookup2(signalScheduleWorker, &EnumParam);
    1056 
    1057     return NULL;
     1183    return __libc_threadLookup2(signalScheduleThreadWorker, &EnumParam);
    10581184}
    10591185
     
    10701196 * @param   pvParam     User parameters (PSIGSCHEDENUMPARAM in our case).
    10711197 */
    1072 int signalScheduleWorker(__LIBC_PTHREAD pCur, __LIBC_PTHREAD pBest, void *pvParam)
     1198static int signalScheduleThreadWorker(__LIBC_PTHREAD pCur, __LIBC_PTHREAD pBest, void *pvParam)
    10731199{
    10741200    PSIGSCHEDENUMPARAM pParam = (PSIGSCHEDENUMPARAM)pvParam;
     
    11081234    /* ok, it's not blocking it so it's ok to use it. */
    11091235    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 */
     1245static 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 */
     1260static 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 */
     1318static 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 */
     1612static 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 */
     1634static 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 */
     1646static int signalJobResume(void)
     1647{
     1648    /** @todo Job control: tell parent and ensure that thread 1 is unfrozen. */
     1649    return 0;
    11101650}
    11111651
     
    11891729        SigInfo.si_tid  = pThrd->tid;
    11901730    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);
    11931735    if (!rc)
    11941736    {
     
    12681810 * This is called by the 16-bit thunker.
    12691811 *
    1270  * @param   uSignal     Signal number - SIG_PFLG_A.
     1812 * @param   uOS2Signal  Signal number - SIG_PFLG_A.
    12711813 * @param   uArg        LIBC sets this to 0 when the target is a LIBC process.
    12721814 *                      If the target is a non-LIBC process it's an EMX signal
    12731815 *                      number.
    12741816 */
    1275 void __libc_back_signalOS2V1Handler32bit(unsigned uSignal, unsigned uArg)
    1276 {
    1277     /*
    1278      * Check the process for pending signals.
    1279      */
    1280 //@todo    __libc_back_signalPending();
     1817void __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);
    12811841
    12821842    /*
     
    12851845    if (uArg)
    12861846    {
    1287         unsigned uSignalLIBC = 0;
     1847        unsigned iSignalNo = 0;
    12881848        switch (uArg)
    12891849        {
    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)
    13121872        {
    13131873            /*
    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.
    13171875             */
    1318             __libc_back_signalRaise(uSignalLIBC, NULL, NULL, __LIBC_BSRF_EXTERNAL);
     1876            signalSchedule(pThrd, iSignalNo, NULL, __LIBC_BSRF_EXTERNAL, NULL);
    13191877        }
    13201878    }
     
    13231881     * Acknowledge the signal.
    13241882     */
    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();
    13261890}
    13271891
     
    13351899void        __libc_back_signalPokeThread(int tid)
    13361900{
    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      */
    13411901    LIBC_ASSERTM(__libc_back_signalSemIsOwner(), "Thread must own signal sem!\n");
    13421902
     
    13451905     */
    13461906    __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 */
     1921static void     signalPokeThread(__LIBC_PTHREAD pThrdPoke)
     1922{
     1923    LIBC_ASSERTM(__libc_back_signalSemIsOwner(), "Thread must own signal sem!\n");
    13491924
    13501925    /*
     
    13541929    {
    13551930        __atomic_xchg(&pThrdPoke->fSigBeingPoked, 1);
    1356         int rc = DosKillThread(tid);
     1931        int rc = DosKillThread(pThrdPoke->tid);
    13571932        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 */
    13691942int         __libc_back_signalRaisePoked(void *pvXcptParams, int tidPoker)
    13701943{
    1371     /*
    1372      * Assert that we do not own the semaphore upon entry.
    1373      */
    13741944    LIBC_ASSERTM(!__libc_back_signalSemIsOwner(), "Thread owns the signal semaphore!!! Bad boy!!\n");
    13751945
     
    13831953         * Take signal semaphore.
    13841954         */
    1385         int SavedErrno = errno;
    13861955        int rc = __libc_back_signalSemRequest();
    13871956        if (!rc)
     
    13901959            {
    13911960                /*
    1392                  * Clear the indicator.
     1961                 * Clear the indicator and deliver signals.
    13931962                 */
    13941963                __atomic_xchg(&pThrd->fSigBeingPoked, 0);
    1395 
    1396                 /*
    1397                  * Check for pending signals.
    1398                  */
    1399 
    1400                 __libc_back_signalSemRelease();
    1401             }
    1402             else
    1403                 __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        }
    14061975    }
    14071976    else
    14081977        LIBC_ASSERTM_FAILED("No thread structure! This is really impossible!\n");
    14091978
    1410     return __LIBC_BSRR_ERROR;
     1979    return -EINVAL;
    14111980}
    14121981
Note: See TracChangeset for help on using the changeset viewer.