Changeset 1618 for trunk/src


Ignore:
Timestamp:
Nov 7, 2004, 3:19:42 PM (21 years ago)
Author:
bird
Message:

More signal debugging and cleanup.

Location:
trunk/src/emx
Files:
2 added
39 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/emx/include/InnoTekLIBC/backend.h

    • Property cvs2svn:cvs-rev changed from 1.9 to 1.10
    r1617 r1618  
    560560 *
    561561 * @returns 0 on success.
    562  * @returns -Negative errno on failure.
     562 * @returns Negative error code (errno) on failure.
    563563 * @param   iSignalNo   Signal number.
    564564 * @param   pSigAct     Pointer to new signal action.
     
    570570
    571571/**
     572 * Change interrupt/restart system call properties for a signal.
     573 *
     574 * @returns 0 on success.
     575 * @returns Negative error code (errno) on failure.
     576 * @param   iSignalNo   Signal number to change interrupt/restart
     577 *                      properties for.
     578 * @param   fFlag       If set Then clear the SA_RESTART from the handler action.
     579 *                      If clear Then set the SA_RESTART from the handler action.
     580 * @remark  The SA_RESTART flag is inherited when using signal().
     581 */
     582int __libc_Back_signalInterrupt(int iSignalNo, int fFlag);
     583
     584/**
    572585 * Changes and/or queries the alternative signal stack settings of a thread.
    573586 *
     
    584597 *
    585598 * @returns 0 on success.
    586  * @returns -1 and errno set to EINVAL on failure.
     599 * @returns Negative error code (errno) on failure.
    587600 * @param   pThrd       Thread to apply this to.
    588601 * @param   iHow        Describes the action taken if pSigSetNew not NULL. Recognized
     
    604617int __libc_Back_signalMask(__LIBC_PTHREAD pThrd, int iHow, const sigset_t * __restrict pSigSetNew, sigset_t * __restrict pSigSetOld);
    605618
     619/**
     620 * Wait for one or more signals and remove and return the first of them
     621 * to occur.
     622 *
     623 * Will return immediately if one of the signals is already pending. If more than
     624 * one signal is pending the signal with highest priority will be returned.
     625 *
     626 * @returns Signal number on success.
     627 * @returns Negative error code (errno) on failure.
     628 * @param   pSigSet     Signals to wait for.
     629 * @param   pSigInfo    Where to store the signal info for the signal
     630 *                      that we accepted.
     631 * @param   pTimeout    Timeout specification. If NULL wait for ever.
     632 */
     633int __libc_Back_signalWait(const sigset_t *pSigSet, siginfo_t *pSigInfo, const struct timespec *pTimeout);
     634
     635/**
     636 * Suspends the current thread till a signal have been handled.
     637 * The signal semaphore is owned.
     638 *
     639 * @returns Negative error code (errno) on failure. (allways fails)
     640 * @param   pSigSet     Temporary signal mask for the thread.
     641 */
     642int __libc_Back_signalSuspend(const sigset_t *pSigSet);
     643
     644/**
     645 * Gets the set of signals which are blocked by the current thread and are
     646 * pending on the process or the calling thread.
     647 *
     648 * @returns 0 indicating success.
     649 * @returns Negative error code (errno) on failure.
     650 * @param   pSigSet     Pointer to signal set where the result is to be stored.
     651 */
     652int __libc_Back_signalPending(sigset_t *pSigSet);
     653
    606654/** @} */
    607655
  • trunk/src/emx/include/InnoTekLIBC/libc.h

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1617 r1618  
    2929
    3030#include <sys/cdefs.h>
     31#include <sys/signal.h>
    3132
    3233__BEGIN_DECLS
     
    4142extern int __libc_gfNoUnix;
    4243
     44/** Signal set of the signals which will interrupt system call execution.
     45 * By default all signals will interrupt syscall execution, since OS/2 can't really
     46 * restart system calls easily.
     47 * Update is protected by the signal semaphore, however read access isn't.
     48 */
     49extern sigset_t __libc_gSignalRestartMask;
     50
    4351__END_DECLS
    4452
  • trunk/src/emx/include/InnoTekLIBC/thread.h

    • Property cvs2svn:cvs-rev changed from 1.8 to 1.9
    r1617 r1618  
    5050*******************************************************************************/
    5151struct _uheap;
     52
     53/**
     54 * sigwait,sigwaitinfo, sigtimedwait data.
     55 */
     56typedef volatile struct __libc_thread_sigwait
     57{
     58    /** Done waitin' indicator.*/
     59    volatile int    fDone;
     60    /** The signals we're waiting for. */
     61    sigset_t        SigSetWait;
     62    /** The where to return signal info. */
     63    siginfo_t       SigInfo;
     64} __LIBC_THREAD_SIGWAIT, *__LIBC_PTHREAD_SIGWAIT;
     65
     66
     67/**
     68 * sigsuspend data.
     69 */
     70typedef volatile struct __libc_thread_sigsuspend
     71{
     72    /** Done waitin' indicator.*/
     73    volatile int    fDone;
     74} __LIBC_THREAD_SIGSUSPEND, *__LIBC_PTHREAD_SIGSUSPEND;
     75
    5276
    5377/**
     
    150174
    151175    /** Thread status, chiefly used for the u member of the thread structure. */
    152     enum enmLIBCThreadStatus
     176    volatile enum enmLIBCThreadStatus
    153177    {
    154178        /** The thread status must be queried from the OS. */
     
    158182        /** The thread is in a sigwait(), sigwaitinfo(), or sigtimedwait() call. */
    159183        enmLIBCThreadStatus_sigwait,
     184        /** The thread is in a sigsuspend() call. */
     185        enmLIBCThreadStatus_sigsuspend,
    160186    }               enmStatus;
    161187
     
    166192    {
    167193        /** enmLIBCThreadStatus_startup:    Begin Thread Arguments. */
    168         struct __libc_thread_startup
     194        struct __libc_thread_u_startup
    169195        {
    170196            /** Thread argument. */
     
    175201
    176202        /** enmLIBCThreadStatus_sigwait:    Thread blocked in sigwait(), sigwaitinfo() or sigtimedwait(). */
    177         struct __libc_thread_sigwait
    178         {
    179             /** The signals we're waiting for. */
    180             sigset_t    SigSetWait;
    181             /** The where to return signal info. */
    182             siginfo_t  *pSigInfo;
    183         } SigWait;
     203        __LIBC_PTHREAD_SIGWAIT      pSigWait;
     204        /** enmLIBCThreadStatus_sigsuspend: Thread blocked in sigsuspend(). */
     205        __LIBC_PTHREAD_SIGSUSPEND   pSigSuspend;
    184206    } u;
    185207
     
    211233} __LIBC_THREAD;
    212234
     235
    213236#ifndef __LIBC_THREAD_DECLARED
    214237#define __LIBC_THREAD_DECLARED
  • trunk/src/emx/src/lib/libc.def

    • Property cvs2svn:cvs-rev changed from 1.75 to 1.76
    r1617 r1618  
    12391239    "___libc_Back_signalStack" @1261
    12401240    "___libc_Back_signalMask" @1262
     1241    "___libc_Back_signalInterrupt" @1263
     1242    "___libc_Back_signalPending" @1264
     1243    "___libc_Back_signalSuspend" @1265
     1244    "___libc_Back_signalWait" @1266
  • trunk/src/emx/src/lib/process/_signal_os2.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1617 r1618  
    3131#include <signal.h>
    3232#include <errno.h>
    33 #include <InnoTekLIBC/signals.h>
     33#include <InnoTekLIBC/libc.h>
     34#include <InnoTekLIBC/backend.h>
    3435#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SIGNAL
    3536#include <InnoTekLIBC/logstrict.h>
     
    5455    {
    5556        LIBC_ASSERTM_FAILED("invalid signal number for SIG_ACK %d\n", iSignalNo);
     57        LIBCLOG_RETURN_P(SIG_ERR);
     58    }
     59    if (pfnHandler == SIG_HOLD)
     60    {
     61        LIBC_ASSERTM_FAILED("SIG_HOLD is not supported by OS/2 style signal handling!\n");
     62        errno = EINVAL;
    5663        LIBCLOG_RETURN_P(SIG_ERR);
    5764    }
     
    96103
    97104        /*
    98          * Gain exclusive access to the signal stuff.
    99          */
    100         if (__libc_back_signalSemRequest())
    101             LIBCLOG_RETURN_P(SIG_ERR);
    102 
    103         /*
    104105         * Do work.
    105106         */
    106107        if (__SIGSET_ISSET(&__libc_gSignalRestartMask, iSignalNo))
    107108            SigAct.sa_flags |= SA_RESTART;
    108         rc = __libc_back_signalAction(iSignalNo, &SigAct, &SigActOld);
    109 
    110         /*
    111          * Release semaphore.
    112          */
    113         __libc_back_signalSemRelease();
     109        rc = __libc_Back_signalAction(iSignalNo, &SigAct, &SigActOld);
    114110
    115111        /*
     
    118114        if (!rc)
    119115            LIBCLOG_RETURN_P(SigActOld.__sigaction_u.__sa_handler);
     116        errno = -rc;
    120117    }
    121118    LIBCLOG_RETURN_P(SIG_ERR);
  • trunk/src/emx/src/lib/process/_signal_sysv.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1617 r1618  
    3131#include <signal.h>
    3232#include <errno.h>
    33 #include <InnoTekLIBC/signals.h>
     33#include <InnoTekLIBC/libc.h>
     34#include <InnoTekLIBC/backend.h>
    3435#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SIGNAL
    3536#include <InnoTekLIBC/logstrict.h>
     
    5960        LIBCLOG_RETURN_P(SIG_ERR);
    6061    }
     62    if (pfnHandler == SIG_HOLD)
     63    {
     64        LIBC_ASSERTM_FAILED("SIG_HOLD is not supported by System V style signal handling!\n");
     65        errno = EINVAL;
     66        LIBCLOG_RETURN_P(SIG_ERR);
     67    }
    6168    if (!__SIGSET_SIG_VALID(iSignalNo))
    6269    {
     
    7481
    7582    /*
    76      * Gain exclusive access to the signal stuff.
    77      */
    78     if (__libc_back_signalSemRequest())
    79         LIBCLOG_RETURN_P(SIG_ERR);
    80 
    81     /*
    8283     * Change signal action.
    8384     */
    8485    if (__SIGSET_ISSET(&__libc_gSignalRestartMask, iSignalNo))
    8586        SigAct.sa_flags |= SA_RESTART;
    86     rc = __libc_back_signalAction(iSignalNo, &SigAct, &SigActOld);
    87 
    88     /*
    89      * Release semaphore.
    90      */
    91     __libc_back_signalSemRelease();
    92 
    93     /*
    94      * Check for errors and return.
    95      */
    96     if (rc)
    97         LIBCLOG_RETURN_P(SIG_ERR);
    98     LIBCLOG_RETURN_P(SigActOld.__sigaction_u.__sa_handler);
     87    rc = __libc_Back_signalAction(iSignalNo, &SigAct, &SigActOld);
     88    if (!rc)
     89        LIBCLOG_RETURN_P(SigActOld.__sigaction_u.__sa_handler);
     90    errno = -rc;
     91    LIBCLOG_RETURN_P(SIG_ERR);
    9992}
    10093
  • trunk/src/emx/src/lib/process/bsd_signal.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1617 r1618  
    3131#include <signal.h>
    3232#include <errno.h>
    33 #include <InnoTekLIBC/signals.h>
     33#include <InnoTekLIBC/libc.h>
     34#include <InnoTekLIBC/backend.h>
    3435#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SIGNAL
    3536#include <InnoTekLIBC/logstrict.h>
     
    5960        LIBCLOG_RETURN_P(SIG_ERR);
    6061    }
     62    if (pfnHandler == SIG_HOLD)
     63    {
     64        LIBC_ASSERTM_FAILED("SIG_HOLD is not supported by BSD style signal handling!\n");
     65        errno = EINVAL;
     66        LIBCLOG_RETURN_P(SIG_ERR);
     67    }
    6168    if (!__SIGSET_SIG_VALID(iSignalNo))
    6269    {
     
    7582
    7683    /*
    77      * Gain exclusive access to the signal stuff.
    78      */
    79     if (__libc_back_signalSemRequest())
    80         LIBCLOG_RETURN_P(SIG_ERR);
    81 
    82     /*
    8384     * Change signal action.
    8485     */
    8586    if (__SIGSET_ISSET(&__libc_gSignalRestartMask, iSignalNo))
    8687        SigAct.sa_flags |= SA_RESTART;
    87     rc = __libc_back_signalAction(iSignalNo, &SigAct, &SigActOld);
    88 
    89     /*
    90      * Release semaphore.
    91      */
    92     __libc_back_signalSemRelease();
    93 
    94     /*
    95      * Check for errors and return.
    96      */
    97     if (rc)
    98         LIBCLOG_RETURN_P(SIG_ERR);
    99     LIBCLOG_RETURN_P(SigActOld.__sigaction_u.__sa_handler);
     88    rc = __libc_Back_signalAction(iSignalNo, &SigAct, &SigActOld);
     89    if (!rc)
     90        LIBCLOG_RETURN_P(SigActOld.__sigaction_u.__sa_handler);
     91    errno = -rc;
     92    LIBCLOG_RETURN_P(SIG_ERR);
    10093}
    10194
  • trunk/src/emx/src/lib/process/killpg.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1617 r1618  
    3131#include <signal.h>
    3232#include <errno.h>
    33 #include <InnoTekLIBC/signals.h>
     33#include <InnoTekLIBC/backend.h>
    3434#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SIGNAL
    3535#include <InnoTekLIBC/logstrict.h>
  • trunk/src/emx/src/lib/process/pause.c

    • Property cvs2svn:cvs-rev changed from 1.3 to 1.4
    r1617 r1618  
    3030*******************************************************************************/
    3131#include "libc-alias.h"
     32#include <unistd.h>
    3233#include <signal.h>
    3334#include <errno.h>
    34 #include <InnoTekLIBC/signals.h>
    35 #include <InnoTekLIBC/thread.h>
    3635#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SIGNAL
    3736#include <InnoTekLIBC/logstrict.h>
  • trunk/src/emx/src/lib/process/raise.c

    • Property cvs2svn:cvs-rev changed from 1.4 to 1.5
    r1617 r1618  
    3232#include <signal.h>
    3333#include <process.h>
    34 #include <InnoTekLIBC/signals.h>
    3534#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SIGNAL
    3635#include <InnoTekLIBC/logstrict.h>
  • trunk/src/emx/src/lib/process/sigblock.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1617 r1618  
    3131#include "libc-alias.h"
    3232#include <signal.h>
    33 #include <errno.h>
    34 #include <InnoTekLIBC/signals.h>
    35 #include <InnoTekLIBC/thread.h>
     33#include <InnoTekLIBC/backend.h>
    3634#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SIGNAL
    3735#include <InnoTekLIBC/logstrict.h>
  • trunk/src/emx/src/lib/process/sighold.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1617 r1618  
    3232#include <signal.h>
    3333#include <errno.h>
    34 #include <InnoTekLIBC/signals.h>
    3534#include <InnoTekLIBC/thread.h>
     35#include <InnoTekLIBC/backend.h>
    3636#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SIGNAL
    3737#include <InnoTekLIBC/logstrict.h>
  • trunk/src/emx/src/lib/process/sigignore.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1617 r1618  
    3232#include <signal.h>
    3333#include <errno.h>
    34 #include <InnoTekLIBC/signals.h>
    3534#include <InnoTekLIBC/thread.h>
     35#include <InnoTekLIBC/backend.h>
    3636#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SIGNAL
    3737#include <InnoTekLIBC/logstrict.h>
  • trunk/src/emx/src/lib/process/siginterrupt.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1617 r1618  
    3333#include <signal.h>
    3434#include <errno.h>
    35 #include <InnoTekLIBC/signals.h>
    36 #include <InnoTekLIBC/thread.h>
     35#include <InnoTekLIBC/backend.h>
    3736#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SIGNAL
    3837#include <InnoTekLIBC/logstrict.h>
     
    5251{
    5352    LIBCLOG_ENTER("iSignalNo=%d fFlag=%d\n", iSignalNo, fFlag);
    54     struct sigaction    SigAct = {{0}};
    55     int                 rc;
    56     int                 rc2 = 0;
    5753
    5854    /*
    59      * Validate.
     55     * Call backend and handler errors.
    6056     */
    61     if (!__SIGSET_SIG_VALID(iSignalNo))
    62     {
    63         LIBC_ASSERTM_FAILED("Invalid signal no %d\n", iSignalNo);
    64         errno = EINVAL;
    65         LIBCLOG_RETURN_INT(-1);
    66     }
    67 
    68     /*
    69      * Gain exclusive access to the signal stuff.
    70      */
    71     if (__libc_back_signalSemRequest())
    72         LIBCLOG_RETURN_INT(-1);
    73 
    74     /*
    75      * Get the previous signal action.
    76      */
    77     rc = __libc_back_signalAction(iSignalNo, NULL, &SigAct);
     57    int rc = __libc_Back_signalInterrupt(iSignalNo, fFlag);
    7858    if (!rc)
    79     {
    80         if (fFlag)
    81         {   /* interrupt */
    82             SigAct.sa_flags &= ~SA_RESTART;
    83             __SIGSET_CLEAR(&__libc_gSignalRestartMask, iSignalNo);
    84         }
    85         else
    86         {   /* restart */
    87             SigAct.sa_flags |= SA_RESTART;
    88             __SIGSET_SET(&__libc_gSignalRestartMask, iSignalNo);
    89         }
    90         rc2 = __libc_back_signalAction(iSignalNo, &SigAct, NULL);
    91     }
    92 
    93     /*
    94      * Release semaphore.
    95      */
    96     __libc_back_signalSemRelease();
    97 
    98 
    99     /*
    100      * Check for failure and return.
    101      */
    102     LIBC_ASSERTM(!rc2, "Impossible!\n");
    103     if (rc || rc2)
    104         LIBCLOG_RETURN_INT(-1);
    105 
    106     LIBCLOG_RETURN_INT(0);
     59        LIBCLOG_RETURN_INT(0);
     60    errno = -rc;
     61    LIBCLOG_RETURN_INT(-1);
    10762}
  • trunk/src/emx/src/lib/process/siginterrupt_data.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1617 r1618  
    2929*******************************************************************************/
    3030#include "libc-alias.h"
    31 #include <InnoTekLIBC/signals.h>
     31#include <InnoTekLIBC/libc.h>
    3232
    3333
  • trunk/src/emx/src/lib/process/signal.c

    • Property cvs2svn:cvs-rev changed from 1.3 to 1.4
    r1617 r1618  
    3030#include "libc-alias.h"
    3131#include <signal.h>
    32 #include <InnoTekLIBC/signals.h>
     32#include <InnoTekLIBC/backend.h>
    3333#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SIGNAL
    3434#include <InnoTekLIBC/logstrict.h>
  • trunk/src/emx/src/lib/process/sigpause.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1617 r1618  
    3434#include <signal.h>
    3535#include <errno.h>
    36 #include <InnoTekLIBC/signals.h>
    37 #include <InnoTekLIBC/thread.h>
     36#include <InnoTekLIBC/backend.h>
    3837#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SIGNAL
    3938#include <InnoTekLIBC/logstrict.h>
  • trunk/src/emx/src/lib/process/sigpause_bsd.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1617 r1618  
    3232#include <signal.h>
    3333#include <errno.h>
    34 #include <InnoTekLIBC/signals.h>
    35 #include <InnoTekLIBC/thread.h>
     34#include <InnoTekLIBC/backend.h>
    3635#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SIGNAL
    3736#include <InnoTekLIBC/logstrict.h>
     37
     38#undef __sigpause_bsd
     39int __sigpause_bsd(int fBlockMask);
    3840
    3941
  • trunk/src/emx/src/lib/process/sigpending.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1617 r1618  
    3131#include "libc-alias.h"
    3232#include <signal.h>
    33 #include <InnoTekLIBC/signals.h>
    34 #include <InnoTekLIBC/thread.h>
     33#include <errno.h>
     34#include <InnoTekLIBC/backend.h>
    3535#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SIGNAL
    3636#include <InnoTekLIBC/logstrict.h>
     
    4747{
    4848    LIBCLOG_ENTER("pSigSet=%p\n", (void *)pSigSet);
    49     __LIBC_THREAD  *pThrd = __libc_threadCurrent();
    50     sigset_t        SigSet;
    5149
    52     __SIGSET_EMPTY(&SigSet);            /* touch it! (paranoia) */
    53 
    54     /*
    55      * Gain exclusive access to the signal stuff.
    56      */
    57     if (__libc_back_signalSemRequest())
    58         LIBCLOG_RETURN_INT(-1);
    59 
    60     /*
    61      * Or the blocked and pending members for this thread.
    62      */
    63     __SIGSET_OR(&SigSet, &__libc_gSignalPending, &pThrd->SigSetPending);
    64     __SIGSET_AND(&SigSet, &pThrd->SigSetBlocked, &SigSet);
    65 
    66     /*
    67      * Release semaphore.
    68      */
    69     __libc_back_signalSemRelease();
    70 
    71     /*
    72      * Copy the set.
    73      */
    74     *pSigSet = SigSet;
    75 
    76     LIBCLOG_RETURN_MSG(0, "ret 0 (*pSigSet={%08lx %08lx})\n", SigSet.__bitmap[1], SigSet.__bitmap[0]);
     50    int rc = __libc_Back_signalPending(pSigSet);
     51    if (!rc)
     52        LIBCLOG_RETURN_MSG(0, "ret 0 (*pSigSet={%08lx %08lx})\n", pSigSet->__bitmap[1], pSigSet->__bitmap[0]);
     53    errno = -rc;
     54    LIBCLOG_RETURN_INT(-1);
    7755}
    7856
  • trunk/src/emx/src/lib/process/sigprocmask.c

    • Property cvs2svn:cvs-rev changed from 1.2 to 1.3
    r1617 r1618  
    8080        if (pSigSetOld)
    8181            *pSigSetOld = SigSetOld;
    82 
    83         LIBCLOG_RETURN_MSG(0, "ret 0 old={%08lx%08lx} new={%08lx%08lx}\n",
    84                            SigSetOld.__bitmap[1], SigSetOld.__bitmap[0],
    85                            SigSetNew.__bitmap[1], SigSetNew.__bitmap[0]);
     82        LIBCLOG_RETURN_MSG(0, "ret 0 old={%08lx%08lx}\n", SigSetOld.__bitmap[1], SigSetOld.__bitmap[0]);
    8683    }
    8784    errno = -rc;
  • trunk/src/emx/src/lib/process/sigrelse.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1617 r1618  
    3232#include <signal.h>
    3333#include <errno.h>
    34 #include <InnoTekLIBC/signals.h>
    35 #include <InnoTekLIBC/thread.h>
     34#include <InnoTekLIBC/backend.h>
    3635#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SIGNAL
    3736#include <InnoTekLIBC/logstrict.h>
  • trunk/src/emx/src/lib/process/sigsetmask.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1617 r1618  
    3131#include "libc-alias.h"
    3232#include <signal.h>
    33 #include <errno.h>
    34 #include <InnoTekLIBC/signals.h>
    35 #include <InnoTekLIBC/thread.h>
     33#include <InnoTekLIBC/backend.h>
    3634#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SIGNAL
    3735#include <InnoTekLIBC/logstrict.h>
  • trunk/src/emx/src/lib/process/sigsuspend.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1617 r1618  
    3333#include <signal.h>
    3434#include <errno.h>
    35 #include <InnoTekLIBC/signals.h>
    3635#include <InnoTekLIBC/thread.h>
     36#include <InnoTekLIBC/backend.h>
    3737#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SIGNAL
    3838#include <InnoTekLIBC/logstrict.h>
     
    4949    LIBCLOG_ENTER("pSigSet=%p {%08lx%08lx}\n",
    5050                  (void *)pSigSet, pSigSet ? pSigSet->__bitmap[1] : 0, pSigSet ? pSigSet->__bitmap[0] : 0);
    51     __LIBC_PTHREAD  pThrd = __libc_threadCurrent();
    52     sigset_t        SigSet;
    5351
    5452    /*
    55      * Make copy of the input (we can safely crash here).
     53     * Backend work.
    5654     */
    57     SigSet = *pSigSet;
    58 
    59     /*
    60      * Gain exclusive access to the signal stuff.
    61      */
    62     if (__libc_back_signalSemRequest())
     55    int rc = __libc_Back_signalSuspend(pSigSet);
     56    if (rc)
     57    {
     58        errno = -rc;
    6359        LIBCLOG_RETURN_INT(-1);
    64 
    65     /*
    66      * Change the signal mask.
    67      */
    68     pThrd->SigSetBlockedOld     = pThrd->SigSetBlocked;
    69     pThrd->fSigSetBlockedOld    = 1;
    70     pThrd->SigSetBlocked        = SigSet;
    71 
    72     /*
    73      * Go to sleep but check for pending signals first.
    74      *
    75      * We have to do this call from within the sem+mustcomplete section.
    76      * The backend function will leave the section.
    77      */
    78     __libc_back_signalSuspend();
    79 
    80 
    81     /*
    82      * Return interrupt failure.
    83      */
    84     errno = EINTR;
    85     LIBCLOG_RETURN_INT(-1);
     60    }
     61    LIBCLOG_RETURN_INT(0);
    8662}
  • trunk/src/emx/src/lib/process/sigtimedwait.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1617 r1618  
    3131#include "libc-alias.h"
    3232#include <signal.h>
    33 #include <assert.h>
    34 #include <InnoTekLIBC/signals.h>
     33#include <errno.h>
    3534#include <InnoTekLIBC/thread.h>
     35#include <InnoTekLIBC/backend.h>
    3636#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SIGNAL
    3737#include <InnoTekLIBC/logstrict.h>
     
    4040
    4141/**
    42  * Wait for a signal to become pending.
     42 * Wait for one or more signals and remove and return the first of them
     43 * to occur.
    4344 *
    44  * @returns 0 on success.
     45 * Will return immediately if one of the signals is already pending. If more than
     46 * one signal is pending the signal with highest priority will be returned.
     47 *
     48 * @returns Signal number on success.
    4549 * @returns -1 on failure, errno set.
    4650 * @param   pSigSet     Signals to wait for.
    4751 * @param   pSigInfo    Where to store the signal info for the signal
    4852 *                      that we accepted.
     53 * @param   pTimeout    Timeout specification. If NULL wait for ever.
    4954 */
    5055int _STD(sigtimedwait)(const sigset_t *pSigSet, siginfo_t *pSigInfo, const struct timespec *pTimeout)
     
    5459                  (void *)pSigInfo,
    5560                  (void *)pTimeout, pTimeout ? pTimeout->tv_sec : ~0, pTimeout ? pTimeout->tv_nsec : ~0);
    56     __LIBC_PTHREAD  pThrd = __libc_threadCurrent();
    57     sigset_t        SigSet;
    58     siginfo_t       SigInfo = {0};
    59     struct timespec Timeout;
    60     int             rc;
    6161
    6262    /*
    63      * Make copy of the input (we can safely crash here).
     63     * Perform the operation.
    6464     */
    65     SigSet = *pSigSet;
    66     if (pTimeout)
    67         Timeout = *pTimeout;
     65    siginfo_t SigInfo;
     66    int rc = __libc_Back_signalWait(pSigSet, &SigInfo, pTimeout);
     67    if (!rc)
     68    {
     69        if (pSigInfo)
     70            *pSigInfo = SigInfo;
     71        LIBCLOG_RETURN_MSG(rc, "ret %d (*pSigInfo={si_signo=%d, si_errno=%d, si_code=%#x, si_timestamp=%#x, si_flags=%#x, si_pid=%d, si_tid=%d, si_uid=%d, si_status=%d, si_addr=%p, si_value=%#08x, si_band=%ld})\n",
     72                           rc, SigInfo.si_signo, SigInfo.si_errno, SigInfo.si_code, SigInfo.si_timestamp,
     73                           SigInfo.si_flags, SigInfo.si_pid, SigInfo.si_tid, SigInfo.si_uid, SigInfo.si_status,
     74                           SigInfo.si_addr, SigInfo.si_value.sigval_int, SigInfo.si_band);
     75    }
    6876
    69     /*
    70      * Gain exclusive access to the signal stuff.
    71      */
    72     if (__libc_back_signalSemRequest())
    73         LIBCLOG_RETURN_INT(-1);
    74 
    75     /*
    76      * Mark thread as blocked in begin in sigtimedwait().
    77      */
    78     if (pThrd->enmStatus != enmLIBCThreadStatus_unknown)
    79     {
    80         LIBC_ASSERTM_FAILED("Must push thread state!\n");
    81         __libc_back_signalSemRelease();
    82         assert(0);
    83         LIBCLOG_RETURN_INT(-1);
    84     }
    85     pThrd->enmStatus            = enmLIBCThreadStatus_sigwait;
    86     pThrd->u.SigWait.SigSetWait = SigSet;
    87     pThrd->u.SigWait.pSigInfo   = &SigInfo;
    88 
    89     /*
    90      * Go to sleep.
    91      *
    92      * We have to do this call from within the sem+mustcomplete section.
    93      * The backend function will leave the section.
    94      */
    95     rc = __libc_back_signalWait(pTimeout ? &Timeout : NULL);
    96 
    97     /*
    98      * Store result.
    99      */
    100     if (pSigInfo)
    101         *pSigInfo = SigInfo;
    102 
    103     LIBCLOG_RETURN_MSG(rc, "ret %d (*pSigInfo={si_signo=%d, si_errno=%d, si_code=%#x, si_pid=%d, si_uid=%d, si_status=%d, si_addr=%p, si_value=%#08x, si_band=%ld})\n",
    104                        rc, SigInfo.si_signo, SigInfo.si_errno, SigInfo.si_code, SigInfo.si_pid, SigInfo.si_uid,
    105                        SigInfo.si_status, SigInfo.si_addr, SigInfo.si_value.sigval_int, SigInfo.si_band);
     77    errno = -rc;
     78    LIBCLOG_RETURN_INT(-1);
    10679}
    10780
  • trunk/src/emx/src/lib/process/sigvec.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1617 r1618  
    3232#include <signal.h>
    3333#include <errno.h>
    34 #include <InnoTekLIBC/signals.h>
    3534#include <InnoTekLIBC/thread.h>
     35#include <InnoTekLIBC/backend.h>
    3636#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SIGNAL
    3737#include <InnoTekLIBC/logstrict.h>
  • trunk/src/emx/src/lib/process/sigwait.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1617 r1618  
    3131#include "libc-alias.h"
    3232#include <signal.h>
    33 #include <InnoTekLIBC/signals.h>
    3433#include <InnoTekLIBC/thread.h>
     34#include <InnoTekLIBC/backend.h>
    3535#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SIGNAL
    3636#include <InnoTekLIBC/logstrict.h>
  • trunk/src/emx/src/lib/process/sigwaitinfo.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1617 r1618  
    3131#include "libc-alias.h"
    3232#include <signal.h>
    33 #include <InnoTekLIBC/signals.h>
    3433#include <InnoTekLIBC/thread.h>
     34#include <InnoTekLIBC/backend.h>
    3535#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SIGNAL
    3636#include <InnoTekLIBC/logstrict.h>
  • trunk/src/emx/src/lib/process/thread_internals.c

    • Property cvs2svn:cvs-rev changed from 1.8 to 1.9
    r1617 r1618  
    4141#include <InnoTekLIBC/thread.h>
    4242#include <InnoTekLIBC/backend.h>
    43 #include <InnoTekLIBC/signals.h>
    4443#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_THREAD
    4544#include <InnoTekLIBC/logstrict.h>
     
    8887    pThrd->iRand = 1;
    8988    pThrd->cRefs = 1;
    90     /* ASSUMES sigemptyset() is equivalent with memsetting a sigset_t. */
    91     if (pParentThrd)
    92     {
    93         /*
    94          * Gain exclusive access to the signal stuff.
    95          */
    96         int rc = __libc_back_signalSemRequest();
    97 
    98         /*
    99          * Copy signal stuff.
    100          */
    101         pThrd->SigSetBlocked    = pParentThrd->SigSetBlocked;
    102         if (pParentThrd->fSigSetBlockedOld)
    103         {
    104             pThrd->SigSetBlockedOld     = pParentThrd->SigSetBlockedOld;
    105             pThrd->fSigSetBlockedOld    = pParentThrd->fSigSetBlockedOld;
    106         }
    107 
    108         /*
    109          * Release semaphore.
    110          */
    111         if (!rc)
    112             __libc_back_signalSemRelease();
    113     }
    114     else
    115     {
    116         /** @todo try find info from parent process. */
    117     }
    118 
    11989    __libc_Back_threadInit(pThrd, pParentThrd);
    12090}
  • trunk/src/emx/src/lib/sys/__init.c

    • Property cvs2svn:cvs-rev changed from 1.17 to 1.18
    r1617 r1618  
    2929#include <InnoTekLIBC/sharedpm.h>
    3030#include <InnoTekLIBC/backend.h>
    31 #include <InnoTekLIBC/signals.h>
    3231#define __LIBC_LOG_GROUP    __LIBC_LOG_GRP_INITTERM
    3332#include <InnoTekLIBC/logstrict.h>
     33#include "signals.h"
    3434
    3535
  • trunk/src/emx/src/lib/sys/__initdll.c

    • Property cvs2svn:cvs-rev changed from 1.17 to 1.18
    r1617 r1618  
    3535#include "syscalls.h"
    3636#include "fs.h"
     37#include "signals.h"
    3738#include <InnoTekLIBC/thread.h>
    3839#include <InnoTekLIBC/libc.h>
    39 #include <InnoTekLIBC/signals.h>
     40#include <InnoTekLIBC/backend.h>
    4041#define __LIBC_LOG_GROUP    __LIBC_LOG_GRP_INITTERM
    4142#include <InnoTekLIBC/logstrict.h>
  • trunk/src/emx/src/lib/sys/b_signalMask.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1617 r1618  
    4848 *
    4949 * @returns 0 on success.
    50  * @returns -1 and errno set to EINVAL on failure.
     50 * @returns Negative error code (errno) on failure.
    5151 * @param   pThrd       Thread to apply this to.
    5252 * @param   iHow        Describes the action taken if pSigSetNew not NULL. Recognized
  • trunk/src/emx/src/lib/sys/b_signalStack.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1617 r1618  
    3030*******************************************************************************/
    3131#include "libc-alias.h"
    32 #define INCL_BASE
    33 #define INCL_FSMACROS
    34 #define INCL_DOSSIGNALS
    35 #include <os2emx.h>
    36 
    3732#include <signal.h>
    3833#include <errno.h>
     
    4136#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_BACK_SIGNAL
    4237#include <InnoTekLIBC/logstrict.h>
    43 #include "syscalls.h"
     38#include "signals.h"
    4439
    4540/**
  • trunk/src/emx/src/lib/sys/b_signalSuspend.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1617 r1618  
    2929*   Header Files                                                               *
    3030*******************************************************************************/
    31 #define INCL_BASE
    32 #define INCL_FSMACROS
    33 #include <os2emx.h>
    34 
     31#include "libc-alias.h"
    3532#include <signal.h>
    3633#include <errno.h>
    37 #include <InnoTekLIBC/signals.h>
    38 #define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SIGNAL
     34#include <InnoTekLIBC/thread.h>
     35#include <InnoTekLIBC/backend.h>
     36#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_BACK_SIGNAL
    3937#include <InnoTekLIBC/logstrict.h>
    40 
    41    
    42 /*******************************************************************************
    43 *   Structures and Typedefs                                                    *
    44 *******************************************************************************/
    45 /** Registration record for signalSuspendXcptHandler(). */
    46 typedef struct XCPTREGREC
    47 {
    48     EXCEPTIONREGISTRATIONRECORD     Core;
    49     /** This event semaphore is signaled when a signal has been
    50      * processed by the current thread. */
    51     HEV                             hev;
    52 } XCPTREGREC, *PXCPTREGREC;
    53 
    54 
    55 /*******************************************************************************
    56 *   Internal Functions                                                         *
    57 *******************************************************************************/
    58 static ULONG _System signalSuspendXcptHandler(PEXCEPTIONREPORTRECORD pXcptRec,  PEXCEPTIONREGISTRATIONRECORD pRegRec, PCONTEXTRECORD pCtx, PVOID pvSomething);
    59 
    60 
    61 /**
    62  * Exception handler use while waitin for signals to be
    63  * delivered to this thread or the process being terminated.
    64  */
    65 static ULONG _System signalSuspendXcptHandler(PEXCEPTIONREPORTRECORD pXcptRec,  PEXCEPTIONREGISTRATIONRECORD pRegRec, PCONTEXTRECORD pCtx, PVOID pvSomething)
    66 {
    67     /* a thread counter? */
    68     /** @todo implement me! */
    69     return XCPT_CONTINUE_SEARCH;
    70 }
     38#include "signals.h"
    7139
    7240
     
    7543 * The signal semaphore is owned.
    7644 */
    77 int         __libc_back_signalSuspend(void)
     45int         __libc_Back_signalSuspend(const sigset_t *pSigSet)
    7846{
    79     LIBCLOG_ENTER("\n");
    80     int         rc;
    81     XCPTREGREC  XcptReg;
    82     FS_VAR();
     47    LIBCLOG_ENTER("pSigSet=%p {%08lx%08lx}\n",
     48                  (void *)pSigSet, pSigSet ? pSigSet->__bitmap[1] : 0, pSigSet ? pSigSet->__bitmap[0] : 0);
     49    __LIBC_PTHREAD              pThrd = __libc_threadCurrent();
     50    sigset_t                    SigSet = *pSigSet;
     51    __LIBC_THREAD_SIGSUSPEND    SigSuspend = {0};
    8352
    8453    /*
    85      * Register
     54     * Gain exclusive access to the signal stuff.
    8655     */
    87     FS_SAVE_LOAD();
    88     XcptReg.Core.ExceptionHandler = signalSuspendXcptHandler;
    89     XcptReg.Core.prev_structure = (void *)~0;
    90     rc = DosCreateEventSem(NULL, &XcptReg.hev, 0, FALSE);
    91     if (!rc)
    92     {
    93         rc = DosSetExceptionHandler(&XcptReg.Core);
    94         if (!rc)
    95         {
    96             PPIB    pPib;
    97             PTIB    pTib;
    98            
    99             /*
    100              * Time to release the semaphore.
    101              */
    102             __libc_back_signalSemRelease();
    103             if (pTib->tib_ptib2->tib2_usMCCount)
    104             {
    105                 LIBC_ASSERTM_FAILED("Deadlock avoided. tried to wait for signal with must complete count %d\n", pTib->tib_ptib2->tib2_usMCCount);
    106                 LIBCLOG_RETURN_INT(-EDEADLK);
    107             }
     56    int rc =__libc_back_signalSemRequest();
     57    if (rc)
     58        LIBCLOG_RETURN_INT(rc);
    10859
    109             /*
    110              * Wait loop.
    111              */
    112             DosGetInfoBlocks(&pTib, &pPib);
    113             for (;;)
    114             {
    115                 rc = DosWaitEventSem(XcptReg.hev, 30*1000);
    116                 if (!rc)
    117                     break;
     60    /*
     61     * Change the signal mask.
     62     */
     63    pThrd->SigSetBlockedOld     = pThrd->SigSetBlocked;
     64    pThrd->fSigSetBlockedOld    = 1;
     65    pThrd->SigSetBlocked        = SigSet;
     66    SigSuspend.fDone            = 0;
     67    pThrd->u.pSigSuspend        = &SigSuspend;
     68    pThrd->enmStatus            = enmLIBCThreadStatus_sigsuspend;
    11869
    119                 /* Avoid deadlocks during termination. */
    120                 if (pPib->pib_flstatus & (0x40/*dying*/ | 0x04/*exiting all*/ | 0x02/*Exiting Thread 1*/ | 0x01/* ExitList */))
    121                 {
    122                     LIBCLOG_MSG("resuming execution, anyhow. the process is terminating. (status=%#lx\n", pPib->pib_flstatus);
    123                     break;
    124                 }
    125             }
    126 
    127             DosUnsetExceptionHandler(&XcptReg.Core);
    128         }
    129         DosCloseEventSem(XcptReg.hev);
    130     }
    131 
    132     FS_RESTORE();
    133     LIBCLOG_RETURN_INT(0);
     70    /*
     71     * Perform signal wait and return.
     72     */
     73    rc = __libc_back_signalWait(pThrd, &SigSuspend.fDone, NULL);
     74    if (rc != EAGAIN)
     75        __libc_back_signalSemRelease();
     76    LIBCLOG_RETURN_INT(rc);
    13477}
    13578
  • trunk/src/emx/src/lib/sys/b_signalWait.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1617 r1618  
    3737#include <errno.h>
    3838#include <386/builtin.h>
    39 #include <InnoTekLIBC/signals.h>
     39#include "signals.h"
    4040#include <InnoTekLIBC/thread.h>
     41#include <InnoTekLIBC/backend.h>
    4142#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SIGNAL
    4243#include <InnoTekLIBC/logstrict.h>
    4344
    4445
     46/**
     47 * Wait for one or more signals and remove and return the first of them
     48 * to occur.
     49 *
     50 * Will return immediately if one of the signals is already pending. If more than
     51 * one signal is pending the signal with highest priority will be returned.
     52 *
     53 * @returns Signal number on success.
     54 * @returns Negative error code (errno) on failure.
     55 * @param   pSigSet     Signals to wait for.
     56 * @param   pSigInfo    Where to store the signal info for the signal
     57 *                      that we accepted.
     58 * @param   pTimeout    Timeout specification. If NULL wait for ever.
     59 */
     60int         __libc_Back_signalWait(const sigset_t *pSigSet, siginfo_t *pSigInfo, const struct timespec *pTimeout)
     61{
     62    LIBCLOG_ENTER("pSigSet=%p {%#08lx%#08lx} pSigInfo=%p pTimeout=%p {%d, %ld}\n",
     63                  (void *)pSigSet, pSigSet ? pSigSet->__bitmap[1] : 0, pSigSet ? pSigSet->__bitmap[0] : 0,
     64                  (void *)pSigInfo,
     65                  (void *)pTimeout, pTimeout ? pTimeout->tv_sec : ~0, pTimeout ? pTimeout->tv_nsec : ~0);
    4566
    46 int         __libc_back_signalWait(const struct timespec *pTimeout)
    47 {
    48     LIBCLOG_ENTER("pTimeout=%p {tv_sec=%d tv_nsec=%ld}\n",
    49                   (void *)pTimeout,
    50                   pTimeout->tv_sec,
    51                   pTimeout->tv_nsec);
    52     /** @todo Implement me */
    53 #if 0
    54     sigset_t        SigSetPending;
     67    __LIBC_PTHREAD  pThrd = __libc_threadCurrent();
     68    sigset_t                        SigSet;
     69    __LIBC_THREAD_SIGWAIT           SigWait = {0};
     70    struct timespec                 Timeout;
     71    int                             rc;
    5572
     73    /*
     74     * Make copy of the input (we can safely crash here).
     75     */
     76    SigSet = *pSigSet;
     77    if (pTimeout)
     78        Timeout = *pTimeout;
     79    __SIGSET_CLEAR(&SigSet, SIGKILL);
     80    __SIGSET_CLEAR(&SigSet, SIGSTOP);
     81    if (__SIGSET_ISEMPTY(&SigSet))
     82    {
     83        LIBC_ASSERTM_FAILED("Signal set is empty! (or you tried to wait for SIGKILL/SIGSTOP)\n");
     84        LIBCLOG_RETURN_INT(-EINVAL);
     85    }
     86
     87    /*
     88     * Gain exclusive access to the signal stuff.
     89     */
     90    rc = __libc_back_signalSemRequest();
     91    if (rc)
     92        LIBCLOG_RETURN_INT(rc);
     93
     94    /*
     95     * Check if the requested signals are pending.
     96     */
    5697    if (    !__SIGSET_ISEMPTY(&pThrd->SigSetPending)
    5798        ||  !__SIGSET_ISEMPTY(&__libc_gSignalPending))
    5899    {
     100        sigset_t    SigSetPending;
    59101        __SIGSET_OR(&SigSetPending, &pThrd->SigSetPending, &__libc_gSignalPending);
    60         __SIGSET_AND(&SigSetPending, &SigSetPending, &SigSet);
     102        __SIGSET_AND(&SigSetPending, &pThrd->SigSetPending, &SigSet);
    61103        if (!__SIGSET_ISEMPTY(&SigSetPending))
    62             rc = __libc_back_signalAccept();
     104        {
     105            rc = __libc_back_signalAccept(pThrd, 0, &SigSetPending, (siginfo_t *)&SigWait.SigInfo);
     106            if (rc > 0)
     107            {
     108                if (pSigInfo)
     109                    *pSigInfo = SigWait.SigInfo;
     110                __libc_back_signalSemRelease();
     111                LIBCLOG_RETURN_INT(rc);
     112            }
     113            LIBC_ASSERT_FAILED();
     114        }
    63115    }
    64 #endif
    65     LIBCLOG_RETURN_INT(-1);
     116
     117    /*
     118     * Mark thread as blocked in sigtimedwait().
     119     */
     120    if (pThrd->enmStatus != enmLIBCThreadStatus_unknown)
     121    {
     122        LIBC_ASSERTM_FAILED("Must push thread state!\n");
     123        __libc_back_signalSemRelease();
     124        LIBCLOG_RETURN_INT(-EDEADLK);
     125    }
     126    SigWait.fDone           = 0;
     127    SigWait.SigSetWait      = SigSet;
     128    SigWait.SigInfo.si_signo= 0;
     129    pThrd->u.pSigWait   = &SigWait;
     130    pThrd->enmStatus    = enmLIBCThreadStatus_sigwait;
     131
     132    /*
     133     * Wait till state changes back and then return according to the wait result.
     134     *
     135     * The result is a bit tricky. EAGAIN means time out and no semaphore. While
     136     * EINTR means that we've been interrupted by the delivery of a signal, which
     137     * might mean that we got what we waited for or that some other signal was
     138     * delivered to this thread. Very simple. :-)
     139     */
     140    rc = __libc_back_signalWait(pThrd, &SigWait.fDone, pTimeout ? &Timeout : NULL);
     141    if (rc != -EAGAIN)
     142        __libc_back_signalSemRelease();
     143    if (rc == -EINTR)
     144    {
     145        if (SigWait.fDone && SigWait.SigInfo.si_signo > 0)
     146        {
     147            rc = SigWait.SigInfo.si_signo;
     148            if (pSigInfo)
     149                *pSigInfo = SigWait.SigInfo;
     150        }
     151    }
     152
     153    LIBCLOG_RETURN_MSG(rc, "ret %d SigWait.SigInfo={si_signo=%d, si_errno=%d, si_code=%#x, si_timestamp=%#x, si_flags=%#x, si_pid=%d, si_tid=%d, si_uid=%d, si_status=%d, si_addr=%p, si_value=%#08x, si_band=%ld}\n",
     154                       rc, SigWait.SigInfo.si_signo, SigWait.SigInfo.si_errno, SigWait.SigInfo.si_code, SigWait.SigInfo.si_timestamp,
     155                       SigWait.SigInfo.si_flags, SigWait.SigInfo.si_pid, SigWait.SigInfo.si_tid, SigWait.SigInfo.si_uid, SigWait.SigInfo.si_status,
     156                       SigWait.SigInfo.si_addr, SigWait.SigInfo.si_value.sigval_int, SigWait.SigInfo.si_band);
    66157}
    67158
  • trunk/src/emx/src/lib/sys/b_threadInit.c

    • Property cvs2svn:cvs-rev changed from 1.4 to 1.5
    r1617 r1618  
    3333#include <emx/syscalls.h>
    3434#include "syscalls.h"
     35#include "signals.h"
    3536#include <InnoTekLIBC/thread.h>
    3637#include <InnoTekLIBC/backend.h>
     
    4142    pThrd->b.sys.fd.hdir = HDIR_CREATE;
    4243    pThrd->b.sys.fd.cFiles = 0;
     44
     45    /*
     46     * Gain exclusive access to the signal stuff.
     47     */
     48    int rc = __libc_back_signalSemRequest();
     49
     50    /*
     51     * Copy signal stuff.
     52     */
     53    pThrd->SigSetBlocked    = pParentThrd->SigSetBlocked;
     54    /** @todo Inheriting fSigSetBlockedOld doesn't make sense! */
     55    if (pParentThrd->fSigSetBlockedOld)
     56    {
     57        pThrd->SigSetBlockedOld     = pParentThrd->SigSetBlockedOld;
     58        pThrd->fSigSetBlockedOld    = pParentThrd->fSigSetBlockedOld;
     59    }
     60
     61    /*
     62     * Release semaphore.
     63     */
     64    if (!rc)
     65        __libc_back_signalSemRelease();
    4366}
    4467
  • trunk/src/emx/src/lib/sys/exceptions.c

    • Property cvs2svn:cvs-rev changed from 1.2 to 1.3
    r1617 r1618  
    3737#include <errno.h>
    3838#include <386/builtin.h>
    39 #include <InnoTekLIBC/signals.h>
    4039#include <InnoTekLIBC/thread.h>
    4140#include <InnoTekLIBC/backend.h>
    4241#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SIGNAL
    4342#include <InnoTekLIBC/logstrict.h>
     43#include "signals.h"
    4444
    4545
  • trunk/src/emx/src/lib/sys/sharedpm.c

    • Property cvs2svn:cvs-rev changed from 1.14 to 1.15
    r1617 r1618  
    892892{
    893893    __atomic_xchg(&gpSPMSelf->fExeInited, 1);
    894     return 0;
    895894}
    896895
  • trunk/src/emx/src/lib/sys/signals.c

    • Property cvs2svn:cvs-rev changed from 1.4 to 1.5
    r1617 r1618  
    10271027         */
    10281028        if (   pThrdSig->enmStatus == enmLIBCThreadStatus_sigwait
    1029             && __SIGSET_ISSET(&pThrdSig->u.SigWait.SigSetWait, iSignalNo))
     1029            && __SIGSET_ISSET(&pThrdSig->u.pSigWait->SigSetWait, iSignalNo))
    10301030        {
    10311031            /*
    10321032             * Wake up a sigwait call.
    10331033             */
    1034             /** @todo install extra exception handler while accessing this. */
    10351034            if (pSigInfo)
    1036                 *pThrdSig->u.SigWait.pSigInfo = *pSigInfo;
     1035                pThrdSig->u.pSigWait->SigInfo = *pSigInfo;
    10371036            else
    1038             {
    1039                 bzero(pThrdSig->u.SigWait.pSigInfo, sizeof(*pThrdSig->u.SigWait.pSigInfo));
    1040                 pThrdSig->u.SigWait.pSigInfo->si_signo = iSignalNo;
    1041             }
     1037                bzero((void *)&pThrdSig->u.pSigWait->SigInfo, sizeof(pThrdSig->u.pSigWait->SigInfo));
     1038            pThrdSig->u.pSigWait->SigInfo.si_signo = iSignalNo;
     1039            pThrdSig->u.pSigWait->fDone = 1;
    10421040            pThrdSig->enmStatus = enmLIBCThreadStatus_unknown;
     1041
     1042            /*
     1043             * Check if there is an unqueued pending signal which we should clear.
     1044             */
     1045            PSIGQUEUED pSig = pThrdSig->SigQueue.pHead;
     1046            while (pSig && pSig->SigInfo.si_signo != iSignalNo)
     1047                pSig = pSig->pNext;
     1048            if (!pSig)
     1049                __SIGSET_CLEAR(&pThrdSig->SigSetPending, iSignalNo);
     1050            else
     1051                __SIGSET_SET(&pThrdSig->SigSetPending, iSignalNo);
     1052
     1053            /*
     1054             * Poke the thread.
     1055             */
    10431056            if (pThrdSig != pThrd)
    10441057                __libc_back_signalPokeThread(pThrdSig);
    1045             LIBCLOG_MSG("wokeup sigwait in thread %d on signal %d.\n", pThrdSig->tid, iSignalNo);
     1058            LIBCLOG_MSG("wokeup sigwait in thread %#x on signal %d.\n", pThrdSig->tid, iSignalNo);
    10461059        }
    10471060        else
     
    11161129                if (pThrdSig != pThrd)
    11171130                    __libc_back_signalPokeThread(pThrdSig);
    1118                 LIBCLOG_MSG("setting %d pending on thread %d's and poking it.\n", pThrdSig->tid, iSignalNo);
     1131                LIBCLOG_MSG("setting %d pending on thread %#x's and poking it.\n", pThrdSig->tid, iSignalNo);
    11191132            }
    11201133        }
     
    13511364
    13521365    /*
    1353      * If we've got a queue node, queue it.
    1354      */
    1355     if (pSig)
    1356     {
    1357         pSig->pNext = NULL;
    1358         pSig->pPrev = pThrdSig->SigQueue.pTail;
    1359         if (pThrdSig->SigQueue.pTail)
    1360             pThrdSig->SigQueue.pTail->pNext = pSig;
     1366     * Check if this was a sig*wait* case.
     1367     */
     1368    if (   pThrdSig->enmStatus == enmLIBCThreadStatus_sigwait
     1369        && __SIGSET_ISSET(&pThrdSig->u.pSigWait->SigSetWait, iSignalNo))
     1370    {
     1371        /*
     1372         * Store result with the thread.
     1373         */
     1374        if (pSig)
     1375            pThrdSig->u.pSigWait->SigInfo = pSig->SigInfo;
    13611376        else
    1362             pThrdSig->SigQueue.pHead = pSig;
    1363         pThrdSig->SigQueue.pTail = pSig;
    1364     }
    1365 
    1366     /*
    1367      * In any case, we set the signal pending and poke the thread.
    1368      */
    1369     __SIGSET_SET(&pThrd->SigSetPending, iSignalNo);
    1370     if (pThrdSig != pThrd)
    1371         __libc_back_signalPokeThread(pThrdSig);
    1372     LIBCLOG_MSG("setting %d pending on thread %d's and poking it.\n", pThrdSig->tid, iSignalNo);
     1377            bzero((void *)&pThrdSig->u.pSigWait->SigInfo, sizeof(pThrdSig->u.pSigWait->SigInfo));
     1378        pThrdSig->u.pSigWait->SigInfo.si_signo = iSignalNo;
     1379        pThrdSig->u.pSigWait->fDone = 1;
     1380        pThrdSig->enmStatus = enmLIBCThreadStatus_unknown;
     1381
     1382        /*
     1383         * Free the signal node.
     1384         */
     1385        pSig->pNext = gpSigQueuedFree;
     1386        gpSigQueuedFree = pSig->pNext;
     1387        gcSigQueuedFree++;
     1388
     1389        /*
     1390         * Check if there is an unqueued pending signal which we should clear.
     1391         */
     1392        pSig = pThrdSig->SigQueue.pHead;
     1393        while (pSig && pSig->SigInfo.si_signo != iSignalNo)
     1394            pSig = pSig->pNext;
     1395        if (!pSig)
     1396            __SIGSET_CLEAR(&pThrdSig->SigSetPending, iSignalNo);
     1397        else
     1398            __SIGSET_SET(&pThrdSig->SigSetPending, iSignalNo);
     1399
     1400        /*
     1401         * Poke the thread.
     1402         */
     1403        if (pThrdSig != pThrd)
     1404            __libc_back_signalPokeThread(pThrdSig);
     1405        LIBCLOG_MSG("wokeup sigwait in thread %#x on signal %d.\n", pThrdSig->tid, iSignalNo);
     1406    }
     1407    else
     1408    {
     1409        /*
     1410         * If we've got a queue node, queue it.
     1411         */
     1412        if (pSig)
     1413        {
     1414            pSig->pNext = NULL;
     1415            pSig->pPrev = pThrdSig->SigQueue.pTail;
     1416            if (pThrdSig->SigQueue.pTail)
     1417                pThrdSig->SigQueue.pTail->pNext = pSig;
     1418            else
     1419                pThrdSig->SigQueue.pHead = pSig;
     1420            pThrdSig->SigQueue.pTail = pSig;
     1421        }
     1422
     1423        /*
     1424         * And in any case set it pending.
     1425         */
     1426        __SIGSET_SET(&pThrd->SigSetPending, iSignalNo);
     1427
     1428        /*
     1429         * Poke the thread.
     1430         */
     1431        if (pThrdSig != pThrd)
     1432            __libc_back_signalPokeThread(pThrdSig);
     1433        LIBCLOG_MSG("setting %d pending on thread %#x's and poking it.\n", pThrdSig->tid, iSignalNo);
     1434    }
     1435
    13731436    LIBCLOG_RETURN_VOID();
    13741437}
     
    13861449{
    13871450    LIBC_ASSERTM(__libc_back_signalSemIsOwner(), "Thread does not own the signal semaphore!!!\n");
     1451
     1452    /*
     1453     * Check for sigwait in the current thread.
     1454     */
     1455    if (   pThrdCur->enmStatus == enmLIBCThreadStatus_sigwait
     1456        && __SIGSET_ISSET(&pThrdCur->u.pSigWait->SigSetWait, iSignalNo))
     1457    {
     1458        pThrdCur->cRefs++;
     1459        return pThrdCur;
     1460    }
    13881461
    13891462    /*
     
    14231496     */
    14241497    if (   pCur->enmStatus == enmLIBCThreadStatus_sigwait
    1425         && __SIGSET_ISSET(&pCur->u.SigWait.SigSetWait, pParam->iSignalNo))
     1498        && __SIGSET_ISSET(&pCur->u.pSigWait->SigSetWait, pParam->iSignalNo))
    14261499    {
    14271500        if (pCur == pParam->pThrd)
     
    14431516        ||  (   pBest
    14441517             && pBest->enmStatus == enmLIBCThreadStatus_sigwait
    1445              && __SIGSET_ISSET(&pCur->u.SigWait.SigSetWait, pParam->iSignalNo)))
     1518             && __SIGSET_ISSET(&pBest->u.pSigWait->SigSetWait, pParam->iSignalNo)))
    14461519        return 0;
    14471520    /* ok, it's not blocking it so it's ok to use it. */
     
    15521625
    15531626        /*
    1554          * Deliver signals /execute signal default actions in this order:
    1555          *   0. Passed in signal (ignores blocking).
    1556          *   1. SIGKILL
    1557          *   2. Realtime signals. (queued)
    1558          *   3. SIGTERM
    1559          *   4. SIGABRT
    1560          *   5. SIGCHLD
    1561          *   6. SIGCONT
    1562          *   7. Ascending from pending mask.
    1563          *
    1564          * Note that 0 and 1 may be violating the POSIX specs.
    1565          */
    1566         if (!iSignalNo || !__SIGSET_ISSET(&pThrd->SigSetPending, iSignalNo))
    1567         {
    1568             iSignalNo = SIGKILL;
    1569             if (!__SIGSET_ISSET(&SigDeliver, SIGKILL))
    1570             {
    1571                 iSignalNo = SIGRTMIN;
    1572                 while (iSignalNo <= SIGRTMAX && !__SIGSET_ISSET(&SigDeliver, iSignalNo))
    1573                     iSignalNo++;
    1574                 if (iSignalNo > SIGRTMAX)
    1575                 {
    1576                     iSignalNo = SIGTERM;
    1577                     if (!__SIGSET_ISSET(&SigDeliver, SIGTERM))
    1578                     {
    1579                         iSignalNo = SIGABRT;
    1580                         if (!__SIGSET_ISSET(&SigDeliver, SIGABRT))
    1581                         {
    1582                             iSignalNo = SIGCHLD;
    1583                             if (!__SIGSET_ISSET(&SigDeliver, SIGCHLD))
    1584                             {
    1585                                 iSignalNo = SIGCONT;
    1586                                 if (!__SIGSET_ISSET(&SigDeliver, SIGCONT))
    1587                                 {
    1588                                     iSignalNo = 1;
    1589                                     while (iSignalNo < SIGRTMIN && !__SIGSET_ISSET(&SigDeliver, iSignalNo))
    1590                                         iSignalNo++;
    1591                                     if (iSignalNo >= SIGRTMIN)
    1592                                     {
    1593                                         LIBC_ASSERTM_FAILED("Internal error!!!\n");
    1594                                         LIBCLOG_RETURN_INT(__LIBC_BSRR_CONTINUE);
    1595                                     }
    1596                                 }
    1597                             }
    1598                         }
    1599                     }
    1600                 }
    1601             }
    1602         }
    1603 
    1604         /*
    1605          * Check if there is a queue element for the signal.
    1606          */
    1607         siginfo_t   SigInfo = {0};
    1608         PSIGQUEUED pSig = pThrd->SigQueue.pHead;
    1609         while (pSig)
    1610         {
    1611             if (pSig->SigInfo.si_signo == iSignalNo)
    1612             {
    1613                 /* unlink */
    1614                 if (pSig->pPrev)
    1615                     pSig->pPrev->pNext    = pSig->pNext;
    1616                 else
    1617                     pThrd->SigQueue.pHead = pSig->pNext;
    1618                 if (pSig->pNext)
    1619                     pSig->pNext->pPrev    = pSig->pPrev;
    1620                 else
    1621                     pThrd->SigQueue.pTail = pSig->pPrev;
    1622 
    1623                 /*
    1624                  * Check if more signals of this type so we can update the
    1625                  * pending mask correctly.
    1626                  */
    1627                 PSIGQUEUED pSigMore = pSig->pNext;
    1628                 while (pSigMore && pSigMore->SigInfo.si_signo != iSignalNo)
    1629                     pSigMore = pSigMore->pNext;
    1630                 if (!pSigMore)
    1631                     __SIGSET_CLEAR(&pThrd->SigSetPending, iSignalNo);
    1632 
    1633                 /*
    1634                  * Copy the signal to the SigInfo structure on the stack
    1635                  * and then release the signal queue structure.
    1636                  */
    1637                 SigInfo = pSig->SigInfo;
    1638                 break;
    1639             }
    1640             /* next */
    1641             pSig = pSig->pNext;
    1642         }
    1643 
    1644         /*
    1645          * If no queued signal data, then we can simply clear it in the pending mask.
    1646          */
    1647         if (!pSig)
    1648         {
    1649             SigInfo.si_signo = iSignalNo;
    1650             __SIGSET_CLEAR(&pThrd->SigSetPending, iSignalNo);
    1651         }
    1652 
    1653 
    1654         /*
    1655          * What to do for this signal?
    1656          */
     1627         * Accept the signal.
     1628         */
     1629        siginfo_t SigInfo;
     1630        if (iSignalNo && __SIGSET_ISSET(&pThrd->SigSetPending, iSignalNo))
     1631            iSignalNo = __libc_back_signalAccept(pThrd, iSignalNo, &SigDeliver, &SigInfo);
     1632        LIBC_ASSERTM(__SIGSET_SIG_VALID(iSignalNo), "iSignalNo=%d\n", iSignalNo);
    16571633        struct sigaction SigAction = gaSignalActions[iSignalNo];
     1634
     1635        /*
     1636         * Check if the thread is waiting in a sig*wait*, because in that
     1637         * case we'll have to notify it that it have to return EINTR.
     1638         */
     1639        if (pThrd->enmStatus == enmLIBCThreadStatus_sigwait)
     1640        {
     1641            bzero((void *)&pThrd->u.pSigWait->SigInfo, sizeof(pThrd->u.pSigWait->SigInfo));
     1642            pThrd->u.pSigWait->fDone = 1;
     1643            pThrd->u.pSigWait = NULL;
     1644            pThrd->enmStatus = enmLIBCThreadStatus_unknown;
     1645        }
     1646        /*
     1647         * Check if the thread is waiting in a sigsuspend, because in that
     1648         * event we'll have to tell it that's the waiting is done.
     1649         */
     1650        else if (   pThrd->enmStatus == enmLIBCThreadStatus_sigsuspend
     1651                 && SigAction.__sigaction_u.__sa_handler != SIG_IGN
     1652                 && (gafSignalProperties[iSignalNo] & SPA_MASK) != SPA_IGNORE
     1653                 && (gafSignalProperties[iSignalNo] & SPA_MASK) != SPA_NEXT
     1654                 && (gafSignalProperties[iSignalNo] & SPA_MASK) != SPA_STOP
     1655                 && (gafSignalProperties[iSignalNo] & SPA_MASK) != SPA_STOPTTY
     1656                 && (gafSignalProperties[iSignalNo] & SPA_MASK) != SPA_RESUME
     1657                 )
     1658        {
     1659            pThrd->u.pSigSuspend->fDone = 1;
     1660            pThrd->u.pSigSuspend = NULL;
     1661            pThrd->enmStatus = enmLIBCThreadStatus_sigsuspend;
     1662        }
     1663
     1664        /*
     1665         * Can we ignore this signal?
     1666         */
    16581667        if (    SigAction.__sigaction_u.__sa_handler == SIG_IGN
    16591668            ||  (   SigAction.__sigaction_u.__sa_handler == SIG_DFL
     
    16661675        }
    16671676
     1677        /*
     1678         * What to do for this signal?
     1679         */
    16681680        if (SigAction.__sigaction_u.__sa_handler == SIG_DFL)
    16691681        {
     
    17301742            if (gafSignalProperties[iSignalNo] & SPP_NOBLOCK)
    17311743                __SIGSET_CLEAR(&SigAction.sa_mask, iSignalNo);
    1732             sigset_t SigSetOld = pThrd->SigSetBlocked;
     1744            sigset_t SigSetOld = !pThrd->fSigSetBlockedOld ? pThrd->SigSetBlocked : pThrd->SigSetBlockedOld;
    17331745            __SIGSET_OR(&pThrd->SigSetBlocked, &pThrd->SigSetBlocked, &SigAction.sa_mask);
    17341746
     
    19922004static int signalJobStop(int iSignalNo)
    19932005{
    1994     LIBC_ASSERTM(__libc_threadCurrent()->tid == 1, "Invalid thread %d\n", __libc_threadCurrent()->tid);
     2006    LIBC_ASSERTM(__libc_threadCurrent()->tid == 1, "Invalid thread %#x\n", __libc_threadCurrent()->tid);
    19952007
    19962008    /*
     
    20192031static int signalJobResume(void)
    20202032{
    2021     LIBC_ASSERTM(__libc_threadCurrent()->tid == 1, "Invalid thread %d\n", __libc_threadCurrent()->tid);
     2033    LIBC_ASSERTM(__libc_threadCurrent()->tid == 1, "Invalid thread %#x\n", __libc_threadCurrent()->tid);
    20222034
    20232035    /*
     
    23582370 *
    23592371 * @returns 0 on success.
    2360  * @returns -Negative errno on failure.
     2372 * @returns Negative error code (errno) on failure.
    23612373 * @param   iSignalNo   Signal number.
    23622374 * @param   pSigAct     Pointer to new signal action.
     
    25572569
    25582570/**
     2571 * Removes a pending signal.
     2572 *
     2573 * The sign can be pending on both thread and process.
     2574 *
     2575 * @returns Signal which was removed.
     2576 * @returns -EINVAL if pSigSet didn't contain any pending signals.
     2577 * @param   pThrd       The thread to evaluate signals on.
     2578 * @param   iSignalNo   Deliver the first signal of this type no matter if it's
     2579 *                      blocked or not. This is for use with hardware signals only!
     2580 * @param   pSigSet     Mask of acceptable signals.
     2581 * @param   pSigInfo    Where to store any SigInfo, optional.
     2582 */
     2583int __libc_back_signalAccept(__LIBC_PTHREAD pThrd, int iSignalNo, sigset_t *pSigSet, siginfo_t *pSigInfo)
     2584{
     2585    LIBCLOG_ENTER("pThrd=%p pSigSet=%p{%#08lx%#08lx} pSigInfo=%p\n", (void *)pThrd,
     2586                  (void *)pSigSet, pSigSet->__bitmap[1], pSigSet->__bitmap[0], (void *)pSigInfo);
     2587
     2588    /*
     2589     * Which signal.
     2590     * Signal delivery priority:
     2591     *   0. Passed in signal (ignores blocking).
     2592     *   1. SIGKILL
     2593     *   2. Realtime signals. (queued)
     2594     *   3. SIGTERM
     2595     *   4. SIGABRT
     2596     *   5. SIGCHLD
     2597     *   6. SIGCONT
     2598     *   7. Ascending from pending mask.
     2599     */
     2600    if (iSignalNo <= 0)
     2601    {
     2602        LIBC_ASSERT(!__SIGSET_ISEMPTY(pSigSet));
     2603        for (iSignalNo = SIGRTMIN; iSignalNo <= SIGRTMAX; iSignalNo++)
     2604            if (__SIGSET_ISSET(pSigSet, iSignalNo))
     2605                break;
     2606        if (iSignalNo > SIGRTMAX)
     2607        {
     2608            iSignalNo = SIGKILL;
     2609            if (!__SIGSET_ISSET(pSigSet, SIGKILL))
     2610            {
     2611                iSignalNo = SIGTERM;
     2612                if (!__SIGSET_ISSET(pSigSet, SIGTERM))
     2613                {
     2614                    iSignalNo = SIGABRT;
     2615                    if (!__SIGSET_ISSET(pSigSet, SIGABRT))
     2616                    {
     2617                        iSignalNo = SIGCHLD;
     2618                        if (!__SIGSET_ISSET(pSigSet, SIGCHLD))
     2619                        {
     2620                            iSignalNo = SIGCONT;
     2621                            if (!__SIGSET_ISSET(pSigSet, SIGCONT))
     2622                            {
     2623                                for (iSignalNo = 1; iSignalNo < SIGRTMIN; iSignalNo++)
     2624                                    if (__SIGSET_ISEMPTY(pSigSet))
     2625                                        break;
     2626                            }
     2627                        }
     2628                    }
     2629                }
     2630            }
     2631        }
     2632    }
     2633
     2634    /*
     2635     * From thread?
     2636     */
     2637    PSIGQUEUED *ppSigHead;
     2638    PSIGQUEUED *ppSigTail;
     2639    sigset_t   *pSigSetPending;
     2640    if (__SIGSET_ISSET(&pThrd->SigSetPending, iSignalNo))
     2641    {
     2642        ppSigHead = &pThrd->SigQueue.pHead;
     2643        ppSigTail = &pThrd->SigQueue.pTail;
     2644        pSigSetPending = &pThrd->SigSetPending;
     2645    }
     2646    else if (__SIGSET_ISSET(&__libc_gSignalPending, iSignalNo))
     2647    {
     2648        ppSigHead = &gpSigQueueHead;
     2649        ppSigTail = &gpSigQueueTail;
     2650        pSigSetPending = &__libc_gSignalPending;
     2651    }
     2652    else
     2653    {
     2654        LIBC_ASSERTM_FAILED("Couldn't find signal %d which should be pending somewhere...\n", iSignalNo);
     2655        iSignalNo = -EINVAL;
     2656        ppSigHead = ppSigTail = NULL;
     2657        pSigSetPending = NULL;
     2658    }
     2659
     2660    if (ppSigHead)
     2661    {
     2662        /*
     2663         * Check if there is a queue element for the signal.
     2664         */
     2665        PSIGQUEUED pSig = *ppSigHead;
     2666        while (pSig)
     2667        {
     2668            if (pSig->SigInfo.si_signo == iSignalNo)
     2669            {
     2670                /* unlink */
     2671                if (pSig->pPrev)
     2672                    pSig->pPrev->pNext  = pSig->pNext;
     2673                else
     2674                    *ppSigHead          = pSig->pNext;
     2675                if (pSig->pNext)
     2676                    pSig->pNext->pPrev  = pSig->pPrev;
     2677                else
     2678                    *ppSigTail          = pSig->pPrev;
     2679
     2680                /*
     2681                 * Check if more signals of this type so we can update the
     2682                 * pending mask correctly.
     2683                 */
     2684                PSIGQUEUED pSigMore = pSig->pNext;
     2685                while (pSigMore && pSigMore->SigInfo.si_signo != iSignalNo)
     2686                    pSigMore = pSigMore->pNext;
     2687                if (!pSigMore)
     2688                    __SIGSET_CLEAR(pSigSetPending, iSignalNo);
     2689
     2690                /*
     2691                 * Copy the signal to the SigInfo structure on the stack
     2692                 * and then release the signal queue structure.
     2693                 */
     2694                if (pSigInfo)
     2695                    *pSigInfo = pSig->SigInfo;
     2696
     2697                /*
     2698                 * Free it.
     2699                 */
     2700                pSig->pNext = gpSigQueuedFree;
     2701                gpSigQueuedFree = pSig->pNext;
     2702                gcSigQueuedFree++;
     2703                break;
     2704            }
     2705            /* next */
     2706            pSig = pSig->pNext;
     2707        }
     2708
     2709        /*
     2710         * If no queued signal data, then we can simply clear it in the pending mask.
     2711         */
     2712        if (!pSig)
     2713        {
     2714            __SIGSET_CLEAR(pSigSetPending, iSignalNo);
     2715            if (pSigInfo)
     2716            {
     2717                bzero(pSigInfo, sizeof(*pSigInfo));
     2718                pSigInfo->si_signo = iSignalNo;
     2719            }
     2720        }
     2721    }
     2722
     2723    LIBCLOG_RETURN_INT(iSignalNo);
     2724}
     2725
     2726/**
     2727 * Wait for an interrupt to be delivered.
     2728 *
     2729 * @returns -ETIMEOUT if we timed out.
     2730 *          The semaphore is not longer owned.
     2731 * @returns -EINTR if interrupt was received and stat changed.
     2732 *          The semaphore is owned.
     2733 * @returns 0 on failure.
     2734 * @param   pThrd       The current thread.
     2735 * @param   pfDone      Pointer to the indicator that we're done waiting.
     2736 * @param   pTimeout    Timeout specification, optional.
     2737 */
     2738int         __libc_back_signalWait(__LIBC_PTHREAD pThrd, volatile int *pfDone, const struct timespec *pTimeout)
     2739{
     2740    LIBCLOG_ENTER("pThrd=%p pfDone=%p{%d} pTimeout=%p{tv_sec=%d tv_nsec=%ld}\n",
     2741                  (void *)pThrd, (void *)pfDone, *pfDone, (void *)pTimeout, pTimeout ? pTimeout->tv_sec : ~0, pTimeout ? pTimeout->tv_nsec : ~0);
     2742    /*
     2743     * Calc wait period.
     2744     */
     2745    ULONG cMillies = SEM_INDEFINITE_WAIT;
     2746    if (pTimeout)
     2747    {
     2748        cMillies = pTimeout->tv_nsec * 1000 + pTimeout->tv_sec / 1000;
     2749        if (!cMillies && pTimeout->tv_sec)
     2750            cMillies = 1;
     2751    }
     2752
     2753    /*
     2754     * Wait for interruption (outside semaphores of course).
     2755     */
     2756    FS_VAR();
     2757    FS_SAVE_LOAD();
     2758    ULONG ulStart = 0;
     2759    DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &ulStart, sizeof(ulStart));
     2760    __libc_back_signalSemRelease();
     2761    for (;;)
     2762    {
     2763        int rc = DosWaitEventSem(ghevWait, cMillies);
     2764
     2765        /*
     2766         * We returned from the wait, but did we do so for the right reason?
     2767         */
     2768        if (rc == ERROR_TIMEOUT || rc == ERROR_SEM_TIMEOUT)
     2769        {
     2770            FS_RESTORE();
     2771            LIBCLOG_RETURN_INT(-EAGAIN);
     2772        }
     2773        rc = __libc_back_signalSemRequest();
     2774        if (*pfDone)
     2775        {
     2776            FS_RESTORE();
     2777            LIBCLOG_RETURN_INT(-EINTR);
     2778        }
     2779
     2780        /*
     2781         * Resume waiting.
     2782         */
     2783        if (cMillies != SEM_INDEFINITE_WAIT)
     2784        {
     2785            ULONG ulEnd = 0;
     2786            DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &ulEnd, sizeof(ulEnd));
     2787            ulEnd -= ulStart;
     2788            if (ulEnd < cMillies)
     2789                cMillies -= ulEnd;
     2790            else
     2791                cMillies = 1;
     2792            ulStart = ulEnd;
     2793        }
     2794    } /* for ever */
     2795}
     2796
     2797
     2798/**
    25592799 * Gets the current timestamp.
    25602800 *
  • trunk/src/emx/src/lib/sys/signals.h

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1617 r1618  
    3030#include <sys/cdefs.h>
    3131#include <signal.h>
     32#include <InnoTekLIBC/libc.h>
    3233#include <InnoTekLIBC/backend.h>
    33 
    34 
    35 /** Signal set of the signals which will interrupt system call execution.
    36  * By default all signals will interrupt syscall execution, since OS/2 can't really
    37  * restart system calls easily.
    38  * Update is protected by the signal semaphore, however read access isn't.
    39  */
    40 extern sigset_t     __libc_gSignalRestartMask;
    4134
    4235/** Signal set for the signals which are pending on a process scope.
     
    5649void        __libc_back_signalPokeProcess(void);
    5750int         __libc_back_signalSuspend(void);
    58 int         __libc_back_signalWait(const struct timespec *pTimeout);
     51int         __libc_back_signalAccept(__LIBC_PTHREAD pThrd, int iSignalNo, sigset_t *pSigSet, siginfo_t *pSigInfo);
     52int         __libc_back_signalWait(__LIBC_PTHREAD pThrd, volatile int *pfDone, const struct timespec *pTimeout);
    5953int         __libc_back_signalSendPidOther(pid_t pid, int iSignalNo, siginfo_t *pSigInfo);
    6054int         __libc_back_signalAction(int iSignalNo, const struct sigaction *pSigAct, struct sigaction *pSigActOld);
Note: See TracChangeset for help on using the changeset viewer.