FreeBSD/sys/compat/linuxkpi/common/src/linux_compat.c
/*
 * Time limited wait for done != 0 with or without signals.
 */
Time limited wait for done != 0 with or without signals.
Time limited wait for done ! = 0 with or without signals .
long
linux_wait_for_timeout_common(struct completion *c, long timeout, int flags)
{
	long end = jiffies + timeout;
	if (SCHEDULER_STOPPED())
		return (0);
	if (flags != 0)
		flags = SLEEPQ_INTERRUPTIBLE | SLEEPQ_SLEEP;
	else
		flags = SLEEPQ_SLEEP;
	for (;;) {
		int ret;
		sleepq_lock(c);
		if (c->done)
			break;
		sleepq_add(c, NULL, "completion", flags, 0);
		sleepq_set_timeout(c, linux_timer_jiffies_until(end));
		if (flags & SLEEPQ_INTERRUPTIBLE)
			ret = sleepq_timedwait_sig(c, 0);
		else
			ret = sleepq_timedwait(c, 0);
		if (ret != 0) {
			if (ret == EWOULDBLOCK)
				return (0);
			else
				return (-ERESTARTSYS);
		}
	}
	c->done--;
	sleepq_release(c);
	return (linux_timer_jiffies_until(end));
}
long linux_wait_for_timeout_common ( struct completion * c , long timeout , int flags ) { long end = jiffies + timeout ; if ( SCHEDULER_STOPPED ( ) ) return ( 0 ) ; if ( flags != 0 ) flags = SLEEPQ_INTERRUPTIBLE | SLEEPQ_SLEEP ; else flags = SLEEPQ_SLEEP ; for ( ; ; ) { int ret ; sleepq_lock ( c ) ; if ( c -> done ) break ; sleepq_add ( c , NULL , " " , flags , 0 ) ; sleepq_set_timeout ( c , linux_timer_jiffies_until ( end ) ) ; if ( flags & SLEEPQ_INTERRUPTIBLE ) ret = sleepq_timedwait_sig ( c , 0 ) ; else ret = sleepq_timedwait ( c , 0 ) ; if ( ret != 0 ) { if ( ret == EWOULDBLOCK ) return ( 0 ) ; else return ( - ERESTARTSYS ) ; } } c -> done -- ; sleepq_release ( c ) ; return ( linux_timer_jiffies_until ( end ) ) ; }
Time limited wait for done != 0 with or without signals.
Time limited wait for done ! = 0 with or without signals .
/* check for timeout or signal */ /* return how many jiffies are left */