xref: /netbsd-src/external/bsd/ntp/dist/libntp/lib/isc/pthreads/condition.c (revision eabc0478de71e4e011a5b4e0392741e01d491794)
1*eabc0478Schristos /*	$NetBSD: condition.c,v 1.2 2024/08/18 20:47:15 christos Exp $	*/
2897be3a4Schristos 
3897be3a4Schristos /*
4897be3a4Schristos  * Copyright (C) 2004, 2005, 2007  Internet Systems Consortium, Inc. ("ISC")
5897be3a4Schristos  * Copyright (C) 1998-2001  Internet Software Consortium.
6897be3a4Schristos  *
7897be3a4Schristos  * Permission to use, copy, modify, and/or distribute this software for any
8897be3a4Schristos  * purpose with or without fee is hereby granted, provided that the above
9897be3a4Schristos  * copyright notice and this permission notice appear in all copies.
10897be3a4Schristos  *
11897be3a4Schristos  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12897be3a4Schristos  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13897be3a4Schristos  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14897be3a4Schristos  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15897be3a4Schristos  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16897be3a4Schristos  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17897be3a4Schristos  * PERFORMANCE OF THIS SOFTWARE.
18897be3a4Schristos  */
19897be3a4Schristos 
20897be3a4Schristos /* Id: condition.c,v 1.36 2007/06/19 23:47:18 tbox Exp  */
21897be3a4Schristos 
22897be3a4Schristos /*! \file */
23897be3a4Schristos 
24897be3a4Schristos #include <config.h>
25897be3a4Schristos 
26897be3a4Schristos #include <errno.h>
27897be3a4Schristos 
28897be3a4Schristos #include <isc/condition.h>
29897be3a4Schristos #include <isc/msgs.h>
30897be3a4Schristos #include <isc/strerror.h>
31897be3a4Schristos #include <isc/string.h>
32897be3a4Schristos #include <isc/time.h>
33897be3a4Schristos #include <isc/util.h>
34897be3a4Schristos 
35897be3a4Schristos isc_result_t
36897be3a4Schristos isc_condition_waituntil(isc_condition_t *c, isc_mutex_t *m, isc_time_t *t) {
37897be3a4Schristos 	int presult;
38897be3a4Schristos 	isc_result_t result;
39897be3a4Schristos 	struct timespec ts;
40897be3a4Schristos 	char strbuf[ISC_STRERRORSIZE];
41897be3a4Schristos 
42897be3a4Schristos 	REQUIRE(c != NULL && m != NULL && t != NULL);
43897be3a4Schristos 
44897be3a4Schristos 	/*
45897be3a4Schristos 	 * POSIX defines a timespec's tv_sec as time_t.
46897be3a4Schristos 	 */
47897be3a4Schristos 	result = isc_time_secondsastimet(t, &ts.tv_sec);
48897be3a4Schristos 	if (result != ISC_R_SUCCESS)
49897be3a4Schristos 		return (result);
50897be3a4Schristos 
51897be3a4Schristos 	/*!
52897be3a4Schristos 	 * POSIX defines a timespec's tv_nsec as long.  isc_time_nanoseconds
53897be3a4Schristos 	 * ensures its return value is < 1 billion, which will fit in a long.
54897be3a4Schristos 	 */
55897be3a4Schristos 	ts.tv_nsec = (long)isc_time_nanoseconds(t);
56897be3a4Schristos 
57897be3a4Schristos 	do {
58897be3a4Schristos #if ISC_MUTEX_PROFILE
59897be3a4Schristos 		presult = pthread_cond_timedwait(c, &m->mutex, &ts);
60897be3a4Schristos #else
61897be3a4Schristos 		presult = pthread_cond_timedwait(c, m, &ts);
62897be3a4Schristos #endif
63897be3a4Schristos 		if (presult == 0)
64897be3a4Schristos 			return (ISC_R_SUCCESS);
65897be3a4Schristos 		if (presult == ETIMEDOUT)
66897be3a4Schristos 			return (ISC_R_TIMEDOUT);
67897be3a4Schristos 	} while (presult == EINTR);
68897be3a4Schristos 
69897be3a4Schristos 	isc__strerror(presult, strbuf, sizeof(strbuf));
70897be3a4Schristos 	UNEXPECTED_ERROR(__FILE__, __LINE__,
71897be3a4Schristos 			 "pthread_cond_timedwait() %s %s",
72897be3a4Schristos 			 isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
73897be3a4Schristos 					ISC_MSG_RETURNED, "returned"),
74897be3a4Schristos 			 strbuf);
75897be3a4Schristos 	return (ISC_R_UNEXPECTED);
76897be3a4Schristos }
77