> Yes, the protocol is asynchronous exactly, not "query/response" sequence, > and could not re-design it now.
Many protocols are that way and should be that way. I wouldn't redesign the protocol unless it was badly designed in the first place. > I could not find sufficient documents or examples about > non-blocking I/O for > newbie like me. By way of experiment, I tried to re-write the code again > with BIO and non-blocking I/O. > The read() wrapping function I made newlly is below; > ------- snip ------- > BIO_set_nbio( cbio, 1 ) ; > BIO_do_connect( cbio ) ; > BIO_do_handshake( cbio ) ; > > int read_ssl( ... ) { > while ( 1 ) { > pthread_mutex_lock( &rw_lock ) ; > int ret = BIO_read( cbio ... ) ; > pthread_mutex_unlock( &rw_lock ) ; > if ( ret > 0 ) { > break ; > } else if ( ! BIO_should_retry( cbio ) ) { > do_something_ERROR() ; > break ; > } > usleep( a_little ) ; // to prevent wasting CPU > } > } > ------- snip ------- > > Will this work correctly with multithreaded asynchronous I/O? > But I think, this way is not better than simple blocking I/O like the > original code. It wastes CPU by the loop and gets poor response > time by the > sleep. Is there any way better than it? That's correct, but very poor for precisely the reasons you explain. You should take a look at the include s_client example. The basic idea is this: Reading: 1) Acquire the mutex. 2) Call SSL_pending. If any bytes are already available, call SSL_read, release the lock, and return. (Note that calls to SSL_write might wind up reading from the socket, so data might already be waiting.) 3) Call SSL_read. If it returns a positive number, release the lock and return the data. If zero, release the lock and return EOF. 4) Pass the return value of SSL_read to SSL_get_error. 5) If the error was not WANT_READ or WANT_WRITE, handle it as appropriate. You can assume it's fatal. 6) If the error was WANT_READ or WANT_WRITE, release the lock, select for read or write as asked, re-acquire the lock, and go back to step 2. Writing: 1) Acquire the mutex. 2) Call SSL_write. If we have sent all of the data, release the lock and returen. 3) If we sent any data, re-adjust to only send the data that remains and go to step 2. 4) If we got a zero, release the lock and return the number of bytes successfully sent. 5) If we got an error, pass the return value to SSL_get_error. 6) If the error is fatal error, release the lock and return. 7) Obey the WANT_READ or WANT_WRITE by releasing the lock, calling 'select', and re-acquiring the lock. Go back to step 2. Note that SSL_read can return WANT_WRITE and SSL_write can return WANT_READ. DS ______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List openssl-users@openssl.org Automated List Manager [EMAIL PROTECTED]