Index: trunk/src/emx/src/lib/libc.def
===================================================================
--- trunk/src/emx/src/lib/libc.def	(revision 1645)
+++ trunk/src/emx/src/lib/libc.def	(revision 1646)
@@ -1267,2 +1267,5 @@
     "__std_wait4" @1289
     "__std_getopt_long_only" @1290
+    "___libc_Back_signalTimer" @1291
+    "__std_getitimer" @1292
+    "__std_setitimer" @1293
Index: trunk/src/emx/src/lib/process/getitimer.c
===================================================================
--- trunk/src/emx/src/lib/process/getitimer.c	(revision 1645)
+++ trunk/src/emx/src/lib/process/getitimer.c	(revision 1646)
@@ -46,5 +46,5 @@
  * @param   pValue  Where to store the value.
  */
-int getitimer(int iWhich, struct itimerval *pValue)
+int _STD(getitimer)(int iWhich, struct itimerval *pValue)
 {
     LIBCLOG_ENTER("iWhich=%d pValue=%p\n", iWhich, (void *)pValue);
Index: trunk/src/emx/src/lib/sys/b_signal.h
===================================================================
--- trunk/src/emx/src/lib/sys/b_signal.h	(revision 1645)
+++ trunk/src/emx/src/lib/sys/b_signal.h	(revision 1646)
@@ -61,4 +61,5 @@
 int         __libc_back_signalInheritPack(__LIBC_PSPMINHSIG *ppSig, size_t *pcbSig);
 void        __libc_back_signalTimerNotifyTerm(void);
+int         __libc_back_signalRaiseInternal(__LIBC_PTHREAD pThrd, int iSignalNo, const siginfo_t *pSigInfo, void *pvQueued, unsigned fFlags);
 
 
Index: trunk/src/emx/src/lib/sys/b_signalTimer.c
===================================================================
--- trunk/src/emx/src/lib/sys/b_signalTimer.c	(revision 1645)
+++ trunk/src/emx/src/lib/sys/b_signalTimer.c	(revision 1646)
@@ -32,4 +32,5 @@
 #define INCL_BASE
 #define INCL_FSMACROS
+#define INCL_DOSINFOSEG
 #define INCL_ERRORS
 #include <os2emx.h>
@@ -82,7 +83,19 @@
 
     /*
+     * Gather stuff we need.
+     */
+    __LIBC_PTHREAD pThrd = __libc_threadCurrent();
+    LIBC_ASSERT(pThrd && pThrd->fInternalThread);
+    GINFOSEG volatile *pGIS = GETGINFOSEG();
+    LIBC_ASSERT(pGIS && pGIS->uchMajorVersion);
+    PPIB pPib = NULL;
+    PTIB pTib = NULL;
+    int rc = DosGetInfoBlocks(&pTib, &pPib);
+    LIBC_ASSERTM(rc == 0 && pPib && pPib->pib_ulpid && pTib && pTib->tib_ptib2->tib2_ultid, "DosGetInfoBlocks -> %d\n", rc);
+
+    /*
      * Change the priority to TC to make the timer more accurate.
      */
-    int rc = DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0);
+    rc = DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0);
     LIBC_ASSERTM(rc == 0, "DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0) -> %d\n", rc);
 
@@ -104,19 +117,47 @@
             break;
         }
+        if (pPib->pib_flstatus & (0x40/*dying*/ | 0x04/*exiting all*/ | 0x02/*Exiting Thread 1*/ | 0x01/*ExitList */))
+        {
+            LIBCLOG_MSG("Timer worker stopping: pPib->pib_flstatus=%#02lx\n", pPib->pib_flstatus);
+            break;
+        }
 
         /*
          * Calc next.
          */
-        if (guInterval)
-            __atomic_xchg(&guNext, signalTimerClock() + guInterval);
-
-        /*
-         * Re-arm timer.
-         */
-        int fArmed = gfArmed;
-        if (gfOneShot)
-        {
-            __libc_back_signalSemRequest();
-            if (gfOneShot && gfArmed)
+        unsigned uTime = pGIS->msecs;
+
+        /*
+         * Take the semaphore.
+         * Recheck for termination afterwards.
+         */
+        int rc = __libc_back_signalSemRequest();
+        if (rc)
+        {
+            LIBCLOG_MSG("Timer worker stopping: __libc_back_signalSemRequest() -> %d\n", rc);
+            break;
+        }
+        if (gfTerminate)
+        {
+            __libc_back_signalSemRelease();
+            LIBCLOG_MSG("Timer worker stopping: gfTerminate=%d\n", gfTerminate);
+            break;
+        }
+        if (pPib->pib_flstatus & (0x40/*dying*/ | 0x04/*exiting all*/ | 0x02/*Exiting Thread 1*/ | 0x01/*ExitList */))
+        {
+            __libc_back_signalSemRelease();
+            LIBCLOG_MSG("Timer worker stopping: pPib->pib_flstatus=%#02lx\n", pPib->pib_flstatus);
+            break;
+        }
+
+
+        /*
+         * Update guNext and if needed rearm the timer.
+         */
+        if (gfArmed)
+        {
+            if (!gfOneShot)
+                __atomic_xchg(&guNext, uTime + guInterval);
+            else
             {
                 __atomic_xchg(&gfOneShot, 0);
@@ -124,25 +165,36 @@
                 if (guInterval)
                 {
-                    __atomic_xchg(&guNext, signalTimerClock() + guInterval + 1);
+                    /*
+                     * Start a new timer.
+                     * Note that we've not compensated for any delays, thus the 2nd SIGALRM may
+                     * be a little bit later than the others. Should matter that much I hope...
+                     */
+                    __atomic_xchg(&guNext, pGIS->msecs + guInterval + 1);
                     rc = DosStartTimer(guInterval, (HSEM)ghevTimer, (PHTIMER)&ghTimer);
                     if (rc)
+                    {
+                        LIBC_ASSERTM_FAILED("DosStartTimer(%d,,) -> rc=%d\n", guInterval, rc);
                         __atomic_xchg(&gfArmed, 0);
+                    }
                 }
+                /*
+                 * It was a one shot setup, we're done.
+                 */
                 else
                     __atomic_xchg(&gfArmed, 0);
             }
 
-            __libc_back_signalSemRelease();
-        }
-
-        /*
-         * Raise a SIGALRM.
-         */
-        if (fArmed)
-        {
-            rc = __libc_Back_signalRaise(SIGALRM, &SigInfo, NULL, 0);
+            /*
+             * Raise SIGALRM.
+             */
+            rc = __libc_back_signalRaiseInternal(pThrd, SIGALRM, &SigInfo, NULL, 0);
             if (rc < 0)
-                LIBCLOG_MSG("__libc_Back_signalRaise -> %d\n", rc);
-        }
+                LIBCLOG_MSG("__libc_back_signalRaiseInternal -> %d\n", rc);
+        }
+
+        /*
+         * Done with the semaphore.
+         */
+        __libc_back_signalSemRelease();
 
         /*
@@ -158,5 +210,5 @@
         if (cCount > 1)
             LIBCLOG_MSG("cCount=%ld missed=%ld shots!\n", cCount, cCount - 1);
-    }
+    } /* loop forever */
 
     /*
Index: trunk/src/emx/src/lib/sys/signals.c
===================================================================
--- trunk/src/emx/src/lib/sys/signals.c	(revision 1645)
+++ trunk/src/emx/src/lib/sys/signals.c	(revision 1646)
@@ -961,5 +961,5 @@
     {
         LIBC_ASSERTM_FAILED("Invalid signal %d\n", iSignalNo);
-        return -EINVAL;
+        LIBCLOG_RETURN_INT(-EINVAL);
     }
 
@@ -974,5 +974,6 @@
         {
             LIBC_ASSERTM_FAILED("No thread structure and we cannot safely create one!\n");
-            return __LIBC_BSRR_PASSITON | (__SIGSET_ISSET(&__libc_gSignalRestartMask, iSignalNo) ? __LIBC_BSRR_RESTART : __LIBC_BSRR_INTERRUPT);
+            int rc = __LIBC_BSRR_PASSITON | (__SIGSET_ISSET(&__libc_gSignalRestartMask, iSignalNo) ? __LIBC_BSRR_RESTART : __LIBC_BSRR_INTERRUPT);
+            LIBCLOG_RETURN_INT(rc);
         }
         pThrd = __libc_threadCurrent();
@@ -980,5 +981,5 @@
         {
             LIBC_ASSERTM_FAILED("Failed to get thread structure!\n");
-            return -ENOMEM;
+            LIBCLOG_RETURN_INT(-ENOMEM);
         }
     }
@@ -1037,4 +1038,75 @@
     return rc;
 }
+
+
+/**
+ * Schedules a signal generated by an internal worker thread.
+ *
+ * @returns 0 on success.
+ * @returns On failure a negative error code (errno.h) is returned.
+ * @param   pThrd               The current thread.
+ * @param   iSignalNo           Signal to raise.
+ * @param   pSigInfo            Pointer to signal info for this signal.
+ *                              NULL is allowed.
+ * @param   pvQueued            If __LIBC_BSRF_QUEUED is set, can optionally point to
+ *                              locally malloced SIGQUEUED node.
+ * @param   fFlags              Flags of the #defines __LIBC_BSRF_* describing how to
+ *                              deliver the signal.
+ */
+int __libc_back_signalRaiseInternal(__LIBC_PTHREAD pThrd, int iSignalNo, const siginfo_t *pSigInfo, void *pvQueued, unsigned fFlags)
+{
+    LIBCLOG_ENTER("pThrd=%p{.tid=%#x} iSignalNo=%d pSigInfo=%p{.si_signo=%d, .si_errno=%d, .si_code=%#x, .si_timestamp=%#x, .si_flags=%#x .si_pid=%#x, .si_pgrp=%#x, .si_tid=%#x, .si_uid=%d, .si_status=%d, .si_addr=%p, .si_value=%p, .si_band=%ld, .si_fd=%d} pvQueued=%p fFlags=%#x\n",
+                  (void *)pThrd, pThrd->tid,
+                  iSignalNo, (void *)pSigInfo,
+                  pSigInfo ? pSigInfo->si_signo : 0,
+                  pSigInfo ? pSigInfo->si_errno : 0,
+                  pSigInfo ? pSigInfo->si_code : 0,
+                  pSigInfo ? pSigInfo->si_timestamp : 0,
+                  pSigInfo ? pSigInfo->si_flags : 0,
+                  pSigInfo ? pSigInfo->si_pid : 0,
+                  pSigInfo ? pSigInfo->si_pgrp : 0,
+                  pSigInfo ? pSigInfo->si_tid : 0,
+                  pSigInfo ? pSigInfo->si_uid : 0,
+                  pSigInfo ? pSigInfo->si_status : 0,
+                  pSigInfo ? pSigInfo->si_addr : 0,
+                  pSigInfo ? pSigInfo->si_value.sigval_ptr : 0,
+                  pSigInfo ? pSigInfo->si_band : 0,
+                  pSigInfo ? pSigInfo->si_fd : 0,
+                  (void *)pvQueued, fFlags);
+
+    /*
+     * Can't be to careful!
+     */
+    LIBC_ASSERT(__libc_back_signalSemIsOwner());
+    LIBC_ASSERT(pThrd->fInternalThread);
+    if (!__SIGSET_SIG_VALID(iSignalNo) || iSignalNo == 0)
+    {
+        LIBC_ASSERTM_FAILED("Invalid signal %d\n", iSignalNo);
+        LIBCLOG_RETURN_INT(-EINVAL);
+    }
+
+    /*
+     * Copy the siginfo structure and fill in the rest of
+     * the SigInfo packet (if we've got one).
+     */
+    siginfo_t SigInfo;
+    SigInfo = *pSigInfo;
+    if (!SigInfo.si_timestamp)
+        SigInfo.si_timestamp = signalTimestamp();
+    if (fFlags & __LIBC_BSRF_QUEUED)
+        SigInfo.si_flags |= __LIBC_SI_QUEUED;
+    if (!SigInfo.si_pid)
+        SigInfo.si_pid = _sys_pid;
+    if (!SigInfo.si_tid)
+        SigInfo.si_tid = pThrd->tid;
+
+    /*
+     * Schedule the signal.
+     */
+    int rc = signalSchedule(pThrd, iSignalNo, &SigInfo, fFlags, fFlags & __LIBC_BSRF_QUEUED ? pvQueued : NULL);
+
+    LIBCLOG_RETURN_INT(rc);
+}
+
 
 
