Commit f1be99832f for openssl.org
commit f1be99832fcb614f24c68a7888a7d0269268ad00
Author: Neil Horman <nhorman@openssl.org>
Date: Mon Jul 6 11:29:42 2026 -0400
Remove the rio_notifier run_once routine
We do this odd thing in rio_notifier. when we initalize it, we call a
run_once routine to call WSAStartup(), create a lock and init a
refcount. The purpose of those last two items is to track the refcount
so that we record how many times we init that rio notifier. when the
refcount reaches zero, we tear down the windows socket api by calling
WSA cleanup, destroy the lock and refcount, and then re-initzlize the
run_once gate.
That last step is sketchy. Even though our implementations of run_once
allow doing so, we should never be re-initing those gates, as its going
to be very prone to races, and they are, well, run_once, so we should
only run them once.
It would be nice to get rid of that behavior, which we can fortunately
do.
https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-wsastartup
Indicates that WSAStartup is internally refcounted, so instead of just
calling it once and tracking when we need to correspondingly call
WSACleanup(), just call it every time we initalize an rio_notifier
object, and call WSACleanup when we tear it down. The Winsock api will
take care of knowing when it actually needs to be cleaned up for us. As
such we can eliminate the run_once routine, the refcount and the lock
entirely.
Reviewed-by: Bob Beck <beck@openssl.org>
Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
MergeDate: Mon Jul 13 14:26:58 2026
(Merged from https://github.com/openssl/openssl/pull/31777)
diff --git a/ssl/rio/rio_notifier.c b/ssl/rio/rio_notifier.c
index ab635aa7a0..3f5225db0e 100644
--- a/ssl/rio/rio_notifier.c
+++ b/ssl/rio/rio_notifier.c
@@ -10,7 +10,6 @@
#include "internal/sockets.h"
#include <openssl/bio.h>
#include <openssl/err.h>
-#include "internal/thread_once.h"
#include "internal/rio_notifier.h"
#if !defined(OPENSSL_SYS_WINDOWS) || RIO_NOTIFIER_METHOD == RIO_NOTIFIER_METHOD_SOCKETPAIR
@@ -30,64 +29,30 @@ static int set_cloexec(int fd)
#if defined(OPENSSL_SYS_WINDOWS)
-static CRYPTO_ONCE ensure_wsa_startup_once = CRYPTO_ONCE_STATIC_INIT;
-static CRYPTO_RWLOCK *wsa_lock;
-static int wsa_started;
-static int wsa_ref;
-
static void ossl_wsa_cleanup(void)
{
- if (wsa_started) {
- wsa_started = 0;
- WSACleanup();
- }
-
- CRYPTO_THREAD_lock_free(wsa_lock);
- wsa_lock = NULL;
+ WSACleanup();
}
-DEFINE_RUN_ONCE_STATIC(do_wsa_startup)
+static int do_wsa_startup(void)
{
WORD versionreq = 0x0202; /* Version 2.2 */
WSADATA wsadata;
- wsa_lock = CRYPTO_THREAD_lock_new();
- if (wsa_lock == NULL)
- return 0;
-
- if (WSAStartup(versionreq, &wsadata) != 0) {
- CRYPTO_THREAD_lock_free(wsa_lock);
- wsa_lock = NULL;
+ if (WSAStartup(versionreq, &wsadata) != 0)
return 0;
- }
- wsa_started = 1;
return 1;
}
static ossl_inline int ensure_wsa_startup(void)
{
- int rv, unused;
-
- rv = RUN_ONCE(&ensure_wsa_startup_once, do_wsa_startup);
- if (rv != 0)
- CRYPTO_atomic_add(&wsa_ref, 1, &unused, wsa_lock);
-
- return rv;
+ return do_wsa_startup();
}
static void wsa_done(void)
{
- int ref;
-
- if (wsa_lock != NULL) {
- CRYPTO_atomic_add(&wsa_ref, -1, &ref, wsa_lock);
- if (ref == 0) {
- ossl_wsa_cleanup();
- ensure_wsa_startup_once = CRYPTO_ONCE_STATIC_INIT;
- wsa_lock = NULL;
- }
- }
+ ossl_wsa_cleanup();
}
#endif
@@ -188,8 +153,6 @@ int ossl_rio_notifier_init(RIO_NOTIFIER *nfy)
if (!ensure_wsa_startup()) {
ERR_raise_data(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR,
"Cannot start Windows sockets");
-
- wsa_done();
return 0;
}
#endif