Clarify some of the I/O issues.
Add case of using select() and blocking I/O with BIOs and why you shouldn't (thanks Bodo!).
This commit is contained in:
parent
279fff0d7f
commit
4041156461
@ -38,16 +38,28 @@ the operation is not implemented in the specific BIO type.
|
||||
=head1 NOTES
|
||||
|
||||
A 0 or -1 return is not necessarily an indication of an error. In
|
||||
particular when the source/sink is non-blocking or of a certain type (for
|
||||
example an SSL BIO can retry even if the underlying connection is blocking)
|
||||
particular when the source/sink is non-blocking or of a certain type
|
||||
it may merely be an indication that no data is currently available and that
|
||||
the application should retry the operation later. L<BIO_should_retry(3)|BIO_should_retry(3)>
|
||||
can be called to determine the precise cause.
|
||||
the application should retry the operation later.
|
||||
|
||||
One technique sometimes used with blocking sockets is to use a system call
|
||||
(such as select(), poll() or eqivalent) to determine when data is available
|
||||
and then call read() to read the data. The eqivalent with BIOs (that is call
|
||||
select() on the underlying I/O structure and then call BIO_read() to
|
||||
read the data) should B<not> be used because a single call to BIO_read()
|
||||
can cause several reads (and writes in the case of SSL BIOs) on the underlying
|
||||
I/O structure and may block as a result. Instead select() (or equivalent)
|
||||
should be combined with non blocking I/O so successive reads will request
|
||||
a retry instead of blocking.
|
||||
|
||||
See the L<BIO_should_retry(3)|BIO_should_retry(3)> for details of how to
|
||||
determine the cause of a retry and other I/O issues.
|
||||
|
||||
If the BIO_gets() function is not supported by a BIO then it possible to
|
||||
work around this by adding a buffering BIO L<BIO_f_buffer(3)|BIO_f_buffer(3)>
|
||||
to the chain.
|
||||
|
||||
=head1 SEE ALSO
|
||||
L<BIO_should_retry(3)|BIO_should_retry(3)>
|
||||
|
||||
TBA
|
||||
|
@ -46,7 +46,7 @@ reason other than reading or writing is the cause of the condition.
|
||||
BIO_get_retry_reason() returns a mask of the cause of a retry condition
|
||||
consisting of the values B<BIO_FLAGS_READ>, B<BIO_FLAGS_WRITE>,
|
||||
B<BIO_FLAGS_IO_SPECIAL> though current BIO types will only set one of
|
||||
these (Q: is this correct?).
|
||||
these.
|
||||
|
||||
BIO_get_retry_BIO() determines the precise reason for the special
|
||||
condition, it returns the BIO that caused this condition and if
|
||||
@ -55,7 +55,7 @@ the reason code and the action that should be taken depends on
|
||||
the type of BIO that resulted in this condition.
|
||||
|
||||
BIO_get_retry_reason() returns the reason for a special condition if
|
||||
pass the relevant BIO, for example as returned by BIO_get_retry_BIO().
|
||||
passed the relevant BIO, for example as returned by BIO_get_retry_BIO().
|
||||
|
||||
=head1 NOTES
|
||||
|
||||
@ -68,27 +68,17 @@ has reached EOF. Some BIO types may place additional information on
|
||||
the error queue. For more details see the individual BIO type manual
|
||||
pages.
|
||||
|
||||
If the underlying I/O structure is in a blocking mode then most BIO
|
||||
types will not signal a retry condition, because the underlying I/O
|
||||
If the underlying I/O structure is in a blocking mode almost all current
|
||||
BIO types will not request a retry, because the underlying I/O
|
||||
calls will not. If the application knows that the BIO type will never
|
||||
signal a retry then it need not call BIO_should_retry() after a failed
|
||||
BIO I/O call. This is typically done with file BIOs.
|
||||
|
||||
The presence of an SSL BIO is an exception to this rule: it can
|
||||
request a retry because the handshake process is underway (either
|
||||
initially or due to a session renegotiation) even if the underlying
|
||||
I/O structure (for example a socket) is in a blocking mode.
|
||||
|
||||
The action an application should take after a BIO has signalled that a
|
||||
retry is required depends on the BIO that caused the retry.
|
||||
|
||||
If the underlying I/O structure is in a blocking mode then the BIO
|
||||
call can be retried immediately. That is something like this can be
|
||||
done:
|
||||
|
||||
do {
|
||||
len = BIO_read(bio, buf, len);
|
||||
} while((len <= 0) && BIO_should_retry(bio));
|
||||
SSL BIOs are the only current exception to this rule: they can request a
|
||||
retry even if the underlying I/O structure is blocking, if a handshake
|
||||
occurs during a call to BIO_read(). An application can retry the failed
|
||||
call immediately or avoid this situation by setting SSL_MODE_AUTO_RETRY
|
||||
on the underlying SSL structure.
|
||||
|
||||
While an application may retry a failed non blocking call immediately
|
||||
this is likely to be very inefficient because the call will fail
|
||||
@ -100,18 +90,9 @@ For example if the cause is ultimately a socket and BIO_should_read()
|
||||
is true then a call to select() may be made to wait until data is
|
||||
available and then retry the BIO operation. By combining the retry
|
||||
conditions of several non blocking BIOs in a single select() call
|
||||
it is possible to service several BIOs in a single thread.
|
||||
|
||||
The cause of the retry condition may not be the same as the call that
|
||||
made it: for example if BIO_write() fails BIO_should_read() can be
|
||||
true. One possible reason for this is that an SSL handshake is taking
|
||||
place.
|
||||
|
||||
Even if data is read from the underlying I/O structure this does not
|
||||
imply that the next BIO I/O call will succeed. For example if an
|
||||
encryption BIO reads only a fraction of a block it will not be
|
||||
able to pass any data to the application until a complete block has
|
||||
been read.
|
||||
it is possible to service several BIOs in a single thread, though
|
||||
the performance may be poor if SSL BIOs are present because long delays
|
||||
can occur during the initial handshake process.
|
||||
|
||||
It is possible for a BIO to block indefinitely if the underlying I/O
|
||||
structure cannot process or return any data. This depends on the behaviour of
|
||||
|
Loading…
x
Reference in New Issue
Block a user