I work on portable applications that often link Open SSL statically, so the "NOTE" in the man page about needing to call OPENSSL_thread_stop() under certain conditions is probably relevant. https://github.com/openssl/openssl/issues/6081 When researching this situation on Windows and how to organize an app to do this, I found the following blog post that describes some workarounds for this basic problem with thread local storage. https://devblogs.microsoft.com/oldnewthing/20191011-00/?p=102989 The most interesting workaround is switching to using "fiber local storage" instead of "thread local storage", but otherwise ignoring fibers. https://learn.microsoft.com/en-us/windows/win32/api/fibersapi/nf-fibersapi-flsalloc I found it through this stack overflow question, which mentions a few more things, like Windows versions: https://stackoverflow.com/questions/74735255/winapi-thread-local-storage-cleanup ------- IDEA/QUESTION 1: This is probably not a short-term change, but in the longer term, is there any chance Open SSL may switch to Windows fiber local storage, thereby simplifying the most common cases where users need to call OPENSSL_thread_stop()? The biggest concern I can see is that I think this fiber local storage idea only works on Windows Vista or later, which raises the question: What is Open SSL's policy about supporting old versions of Windows that Microsoft no longer supports (XP/2000)? (Perhaps it could be a (pre-build) configure option, or auto-determined at runtime using GetProcAddress()...) Outside Open SSL, I'm not sure, but maybe an application could use this to keep track of when to call OPENSSL_thread_stop()? Although depending on the structure of the application, ensuring each thread that might have allocated storage in Open SSL also allocates an app-level FLS per-thread slot with FlsSetValue() could be more difficult than just directly calling OPENSSL_thread_stop() as each thread ends... ------- QUESTION 2: When a thread is ending, is it necessary to call OPENSSL_thread_stop_ex() for every allocated OSSL_LIB_CTX, or is a single call to OPENSSL_thread_stop() sufficient? The one man page for both functions has a "NOTE" section doesn't mention OPENSSL_thread_stop_ex(), only OPENSSL_thread_stop(), and earlier sections don't say anything about the apparent global nature of the non-"ex" function: In code, it looks like the "if (arg != NULL && curr->arg != arg)" condition in the underlying init_thread_stop() function (crypto/initthread.c) suggests that NULL is treated specially to free up thread local storage related to everything (all OSSL_LIB_CTX's), while non-NULL only cleans up the indicated OSSL_LIB_CTX? (But I'm not familiar enough with how this code works to be confident of this conclusion, or why exposing a cleanup-only-a-single-context option in the public API is even useful.) - Matthew Ogilvie