I’m using a
TROSuperHTTPServer instance with the appropriate options for it to use OpenSSL and so provide an HTTPs set of services.
Sadly, I’m getting frequent access violations inside this project and after long debugging sessions, I figured out what’s causing them.
Basically, this happens when deactivating the server instance which leads to
DisconnectClients which ultimately calls
TROSocketOpenSSL.DeInit which in turn calls
In parallel, there is a
TROSocketWorkerThread instance that has called
TROAsyncSocket.IntEndReceive which called
TROSocketOpenSSL.Read and itself is blocked inside
But the OpenSSL documentation is very clear on the subject,
SSL_free should never be called when any other operation is in progress on the same
The SDK does not respect this and it triggers an access violation inside OpenSSL DLL which in my case even kills the entire server because this exception is never caught by any
An unsatisfactory workaround is this, inside
if Assigned(fSSL) then begin
var curThreadId := GetCurrentThreadId;
if fSSLThreadId <> curThreadId then
fSSL := nil;
Basically, I write down the Thread Id that called
SSL_new (two locations) and if it is different from the caller thread id, I wait for 2 seconds.
To me, this is not satisfactory for two reasons:
- The thread Id could have been reused if the original thread has died in between
- The delay is a fixed magic number which makes little sense
The first issue is highly unlikely as the worker thread has no reason to have disappeared before
DeInit is called. To be on the safe side, I could open a handle to the thread that called
SSL_new and use
GetThreadId to do my comparison later on, but it felt too complex for a “workaround”.
For the second issue, I really hope there is another way to write a fix. Note that I thought about an empty
try..except around the call to
SSL_read but it’s even more disturbing than the hard coded delay. Really, exceptions should never be silently trapped if there is another way.