If a thread blocks on a condition with cv_wait(9F), and that condition does not occur, it can wait forever. One way to prevent this is to establish a callback with timeout(9F). This callback sets a flag indicating that the condition did not occur normally, and then unblocks the thread. The notified thread then notices that the condition did not occur and can return an error.
A better solution is to use cv_timedwait(9F). An absolute wait time is passed to cv_timedwait(9F), which returns -1 if the time is reached and the event has not occurred. It returns a positive value if the condition is met.
cv_timedwait(9F) requires an absolute wait time expressed in clock ticks since the system was last rebooted. This can be determined by retrieving the current value with ddi_get_lbolt(9F). The driver usually has a maximum number of seconds or microseconds to wait, so this value is converted to clock ticks with drv_usectohz(9F) and added to the value from ddi_get_lbolt(9F).
Example 3-2 shows how to use cv_timedwait(9F) to wait up to five seconds to access the device before returning EIO to the caller.
clock_t cur_ticks, to;
mutex_enter(&xsp->mu);
while (xsp->busy) {
cur_ticks = ddi_get_lbolt();
to = cur_ticks + drv_usectohz(5000000); /* 5 seconds from now */
if (cv_timedwait(&xsp->cv, &xsp->mu, to) == -1) {
/*
* The timeout time 'to' was reached without the
* condition being signalled.
*/
/* tidy up and exit */
mutex_exit(&xsp->mu);
return (EIO);
}
}
xsp->busy = 1;
mutex_exit(&xsp->mu);