Hello,
Our OpenSSL-enabled server is built upon non-blocking IO with IO
completion ports on Windows. Everything is very efficient and fast, but
there is a nagging issue with double-buffering.
Essentially, when OpenSSL calls BIO_write our application buffers the
data to be sent, and initiates an IOCP write request on this buffer and
returns with success. If there is a pending IOCP request we call
BIO_set_retry_write and return with failure.
Similarly, when OpenSSL calls BIO_read, we satisfy the request from a
buffer that is fed by completed IOCP requests. If there's no data in
the buffer we call BIO_set_retry_read and return with failure.
This could be changed to be much more efficient:
BIO_write could call BIO_set_retry_write immediately and return with
failure, while also initiating an IOCP write request on the buffer it
received in the call. When the IOCP request completes successfully, the
retried BIO_write call could be satisfied.
BIO_read could initiate an IOCP_read, and, again, call
BIO_set_retry_read and return with failure. When the IOCP request
completes successfully the retried BIO_read call could be satisfied.
For this to work, however, it would have to be guaranteed that OpenSSL,
when retrying a BIO_read, it does so with the same buffer, and for at
least as much data as was originally requested. Of course, the buffer
must remain valid between the two calls. Also, when retrying a
BIO_write, the call must be for the same buffer and for at least as
much data as was originally written - and the buffer must remain the
same during the two calls.
Is this something we could count on? We could save quite a bit of CPU
time and memory by not having to copy data into temporary buffers.
Thanks in advance,
-Marton Anka