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