Open Transport supplies robust timer services that are synchronized with the STREAMS environment and are supported by using special STREAMS messages. The function mi_timer_alloc creates one of these special STREAMS messages:
mblk_t* mi_timer_alloc(queue_t* targetQueue, size_t size);
Calling this function creates a STREAMS timer message of the requested size that is targeted to the specified STREAMS queue. Upper queues must be used as the targets of timer messages because timer messages enter target queues as M_PCSIG messages, which can never legitimately arrive from an upper queue but might legitimately arrive from a lower queue.
void mi_timer(mblk_t* timerMsg, unsigned long milliSeconds);
This function schedules the timerMsg (created using mi_timer_alloc ) to be placed on the target STREAMS queue at a specified future time.
To reset a timer, you need only call mi_timer with the new time. There is no need to call mi_timer_cancel.
void mi_timer_cancel(mbk_t* timerMsg);
This function cancels an outstanding timer message. The timerMsg message is not destroyed but will no longer be delivered to the target queue. It may be rescheduled by using mi_timer at a later time.
void mi_timer_free (mblk_t* timerMsg);
This function cancels and frees the specified timer message ( mi_timer_cancel does not free the message). Never call freeb or freemsg for a timer message.
Boolean mi_timer_valid (mblk_t* timerMsg);
Timer messages enter the target queue as M_PCSIG messages. Whenever a queue that can receive a timer message receives an M_PCSIG message, it should call mi_timer_valid, passing the M_PCSIG message as a parameter. If the function returns true, then the timer message is valid and should be processed. If the function returns false, then the timer message was either deleted or canceled. In this case, ignore the message and don't free it.
The mi_timer_valid function may not be called at interrupt time.
mblk_t* mi_timer_qswitch
(mblk_t* timerMsg, queue_t* q, mblk_t* newTimerMsg);
This function is called to change the target queue of a timer message. The caller must be in a context that blocks delivery of the timer message to the target queue's put or service routine during the call. For example, the caller must already be in a put or service routine and won't be processing a timer message reentrantly.
The timerMsg parameter is the timer message that is to be moved to the new queue. The q parameter is the new target queue for the timer message. The newTimerMsg parameter is a copy of the timer message that is pointed to by timerMsg. The routine returns a pointer to the timer message that lives on--either timerMsg or newTimerMsg. The other message is freed. If no new message is provided ( newTimerMsg is null ), but a message is required to do the switch successfully, a null pointer is returned. Both timerMsg and newTimerMsg are copies of the same message. On return, these pointers must be treated as invalid pointers and only the function return pointer can be considered valid.