in src/outgoing.c [117:200]
apr_status_t serf__conn_update_pollset(serf_connection_t *conn)
{
serf_context_t *ctx = conn->ctx;
apr_status_t status;
apr_pollfd_t desc = { 0 };
bool data_waiting;
if (!conn->skt) {
return APR_SUCCESS;
}
/* Remove the socket from the poll set. */
desc.desc_type = APR_POLL_SOCKET;
desc.desc.s = conn->skt;
desc.reqevents = conn->io.reqevents;
status = ctx->pollset_rm(ctx->pollset_baton,
&desc, &conn->io);
if (status && !APR_STATUS_IS_NOTFOUND(status))
return status;
/* Now put it back in with the correct read/write values. */
desc.reqevents = APR_POLLHUP | APR_POLLERR;
/* If we are not connected yet, we just want to know when we are */
if (conn->wait_for_connect) {
data_waiting = true;
desc.reqevents |= APR_POLLOUT;
}
else {
/* Directly look at the connection data. While this may look
more expensive than the cheap checks later this peek is
just checking a bit of ram.
But it also has the nice side effect of removing references
from the aggregate to requests that are done.
*/
data_waiting = serf_pump__data_pending(&conn->pump)
&& !conn->pump.done_writing;
if (data_waiting) {
desc.reqevents |= APR_POLLOUT;
}
}
if ((conn->written_reqs || conn->unwritten_reqs) &&
conn->state != SERF_CONN_INIT) {
/* If there are any outstanding events, then we want to read. */
/* ### not true. we only want to read IF we have sent some data */
desc.reqevents |= APR_POLLIN;
/* Don't write if OpenSSL told us that it needs to read data first. */
if (! conn->pump.stop_writing && !data_waiting) {
/* This check is duplicated in write_to_connection() */
if ((conn->probable_keepalive_limit &&
conn->completed_requests > conn->probable_keepalive_limit) ||
(conn->max_outstanding_requests &&
REQS_IN_PROGRESS(conn) >= conn->max_outstanding_requests)) {
/* we wouldn't try to write any way right now. */
}
else if (request_pending(NULL, conn)) {
desc.reqevents |= APR_POLLOUT;
}
}
}
/* If we can have async responses, always look for something to read. */
if (conn->framing_type != SERF_CONNECTION_FRAMING_TYPE_HTTP1
|| conn->async_responses)
{
desc.reqevents |= APR_POLLIN;
}
/* save our reqevents, so we can pass it in to remove later. */
conn->io.reqevents = desc.reqevents;
/* Note: even if we don't want to read/write this socket, we still
* want to poll it for hangups and errors.
*/
return ctx->pollset_add(ctx->pollset_baton,
&desc, &conn->io);
}