xref: /freebsd/contrib/ntp/libntp/lib/isc/pthreads/condition.c (revision a466cc55373fc3cf86837f09da729535b57e69a1)
1  /*
2   * Copyright (C) 2004, 2005, 2007  Internet Systems Consortium, Inc. ("ISC")
3   * Copyright (C) 1998-2001  Internet Software Consortium.
4   *
5   * Permission to use, copy, modify, and/or distribute this software for any
6   * purpose with or without fee is hereby granted, provided that the above
7   * copyright notice and this permission notice appear in all copies.
8   *
9   * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10   * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11   * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12   * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13   * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14   * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15   * PERFORMANCE OF THIS SOFTWARE.
16   */
17  
18  /* $Id: condition.c,v 1.36 2007/06/19 23:47:18 tbox Exp $ */
19  
20  /*! \file */
21  
22  #include <config.h>
23  
24  #include <errno.h>
25  
26  #include <isc/condition.h>
27  #include <isc/msgs.h>
28  #include <isc/strerror.h>
29  #include <isc/string.h>
30  #include <isc/time.h>
31  #include <isc/util.h>
32  
33  isc_result_t
isc_condition_waituntil(isc_condition_t * c,isc_mutex_t * m,isc_time_t * t)34  isc_condition_waituntil(isc_condition_t *c, isc_mutex_t *m, isc_time_t *t) {
35  	int presult;
36  	isc_result_t result;
37  	struct timespec ts;
38  	char strbuf[ISC_STRERRORSIZE];
39  
40  	REQUIRE(c != NULL && m != NULL && t != NULL);
41  
42  	/*
43  	 * POSIX defines a timespec's tv_sec as time_t.
44  	 */
45  	result = isc_time_secondsastimet(t, &ts.tv_sec);
46  	if (result != ISC_R_SUCCESS)
47  		return (result);
48  
49  	/*!
50  	 * POSIX defines a timespec's tv_nsec as long.  isc_time_nanoseconds
51  	 * ensures its return value is < 1 billion, which will fit in a long.
52  	 */
53  	ts.tv_nsec = (long)isc_time_nanoseconds(t);
54  
55  	do {
56  #if ISC_MUTEX_PROFILE
57  		presult = pthread_cond_timedwait(c, &m->mutex, &ts);
58  #else
59  		presult = pthread_cond_timedwait(c, m, &ts);
60  #endif
61  		if (presult == 0)
62  			return (ISC_R_SUCCESS);
63  		if (presult == ETIMEDOUT)
64  			return (ISC_R_TIMEDOUT);
65  	} while (presult == EINTR);
66  
67  	isc__strerror(presult, strbuf, sizeof(strbuf));
68  	UNEXPECTED_ERROR(__FILE__, __LINE__,
69  			 "pthread_cond_timedwait() %s %s",
70  			 isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
71  					ISC_MSG_RETURNED, "returned"),
72  			 strbuf);
73  	return (ISC_R_UNEXPECTED);
74  }
75