Unlike DosAsyncTimer, DosStartTimer does not stop after the first interval is counted. The timer runs asynchronously to the calling thread, enabling the thread to perform other operations while it is waiting for the specified time intervals to expire. The system notifies the application of the timer's expirations by posting an event semaphore.
The application resets the semaphore before starting the timer and whenever the system posts the semaphore. The application can use the value returned in the post-counting parameter by DosResetEventSem to assure the semaphore was posted only once before it was reset.
The following code fragment starts a timer and then waits on and resets the associated event semaphore. Assume that the handle of the targeted event semaphore has been placed into SemHandle.
#define INCL_DOSDATETIME /* Date and time values */ #include <os2.h> #include <stdio.h> ULONG ulTimeInterval; /* Interval (milliseconds) */ HSEM hsemSemHandle; /* Event-semaphore handle */ HTIMER hHandle; /* Timer handle (returned) */ APIRET ulrc; /* Return code */ ulTimeInterval = 30000; /* Set the periodic time interval to */ /* elapse every 30 seconds */ ulrc = DosStartTimer(ulTimeInterval, hsemSemHandle, &hHandle); if (ulrc != 0) { printf("DosStartTimer error: return code = %ld", ulrc); return; }
On successful return, Handle will contain the handle of this periodic timer. DosStopTimer can be used later to stop the periodic timer.
A repeated timer will continue to count the interval and post the semaphore until the application terminates or the application uses DosStopTimer to stop the timer explicitly. The following code fragment shows how to stop a periodic timer that has been started previously with DosStartTimer:
#define INCL_DOSDATETIME /* Date and time values */ #include <os2.h> #include <stdio.h> HTIMER hHandle; /* Handle of the timer */ APIRET ulrc; /* Return code */ ulrc = DosStopTimer(hHandle); if (ulrc != 0) { printf("DosStopTimer error: return code = %ld", ulrc); return; }
Before starting the timer, the event semaphore must be reset. If the semaphore does not exist, the thread can create it with DosCreateEventSem, specifying its initial state as reset. If the semaphore was previously created by the same process, the thread resets it by calling DosResetEventSem. If the semaphore was previously created by another process, then the thread calls DosOpenEventSem to gain access to the semaphore before calling DosResetEventSem.
Next, the thread calls DosStartTimer, specifying the handle of the event semaphore and the desired time interval. The thread can then perform other tasks. However, in order for the application to be notified of the timer's expirations, one or more threads in the application must call DosWaitEventSem.
When the time interval expires, the system posts the semaphore, and any threads that were blocked on DosWaitEventSem requests can resume their execution. Each time the semaphore is posted, it must be reset with DosResetEventSem before the next timer expiration. DosWaitEventSem must also be called to wait for the semaphore to be posted again.
In addition to resetting the event semaphore, DosResetEventSem returns the semaphore's post count (the number of times the semaphore has been posted since the last time it was in the set state). An application can use the post count to ensure that it has not missed a timer interval; if the post count is greater than one, the application missed a timer interval.