xref: /netbsd-src/external/bsd/ntp/dist/libntp/lib/isc/win32/once.c (revision eabc0478de71e4e011a5b4e0392741e01d491794)
1*eabc0478Schristos /*	$NetBSD: once.c,v 1.2 2024/08/18 20:47:16 christos Exp $	*/
2897be3a4Schristos 
3897be3a4Schristos /*
4897be3a4Schristos  * Copyright (C) 2004, 2007  Internet Systems Consortium, Inc. ("ISC")
5897be3a4Schristos  * Copyright (C) 1999-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: once.c,v 1.12 2007/06/18 23:47:49 tbox Exp  */
21897be3a4Schristos 
22897be3a4Schristos /* Principal Authors: DCL */
23897be3a4Schristos 
24897be3a4Schristos #include <config.h>
25897be3a4Schristos 
26897be3a4Schristos #include <windows.h>
27897be3a4Schristos 
28897be3a4Schristos #include <isc/once.h>
29897be3a4Schristos #include <isc/assertions.h>
30897be3a4Schristos #include <isc/util.h>
31897be3a4Schristos 
32897be3a4Schristos isc_result_t
33897be3a4Schristos isc_once_do(isc_once_t *controller, void(*function)(void)) {
34897be3a4Schristos 	REQUIRE(controller != NULL && function != NULL);
35897be3a4Schristos 
36897be3a4Schristos 	if (controller->status == ISC_ONCE_INIT_NEEDED) {
37897be3a4Schristos 
38897be3a4Schristos 		if (InterlockedDecrement(&controller->counter) == 0) {
39897be3a4Schristos 			if (controller->status == ISC_ONCE_INIT_NEEDED) {
40897be3a4Schristos 				function();
41897be3a4Schristos 				controller->status = ISC_ONCE_INIT_DONE;
42897be3a4Schristos 			}
43897be3a4Schristos 		} else {
44897be3a4Schristos 			while (controller->status == ISC_ONCE_INIT_NEEDED) {
45897be3a4Schristos 				/*
46897be3a4Schristos 				 * Sleep(0) indicates that this thread
47897be3a4Schristos 				 * should be suspended to allow other
48897be3a4Schristos 				 * waiting threads to execute.
49897be3a4Schristos 				 */
50897be3a4Schristos 				Sleep(0);
51897be3a4Schristos 			}
52897be3a4Schristos 		}
53897be3a4Schristos 	}
54897be3a4Schristos 
55897be3a4Schristos 	return (ISC_R_SUCCESS);
56897be3a4Schristos }
57