2
0
Fork 0

[streams] improve stream handling, hopefully fixes bug with lingering backend connections

- reset backend_source before backend_drain; first tell the backend we
  are not interested in data anymore, then force closing the outgoing
  data
- as backend_drain might get reopened for a Connection: upgrade, the
  backend cannot rely on backend_drain->out.is_closed, but waits for a
  disconnect (which will also release the last reference).  the same is
  done for backend_source, so a backend can just wait for both reference
  counts to drop to zero before actually closing the backend connection
  (unless it keeps the streams alive itself).

Change-Id: Ibfe7985debd71580dbb78b985abaf946f59e3024
This commit is contained in:
Stefan Bühler 2015-08-08 16:12:59 +02:00
parent 4375aba174
commit 535f6b4afb
2 changed files with 11 additions and 17 deletions

View File

@ -80,7 +80,13 @@ static void check_response_header(liStreamHttpResponse* shr) {
}
shr->response_headers_finished = TRUE;
shr->vr->backend_drain->out->is_closed = FALSE;
li_vrequest_connection_upgrade(shr->vr, shr->vr->backend_drain, &shr->stream);
{
/* li_vrequest_connection_upgrade releases vr->backend_drain; keep our own reference */
liStream *backend_drain = shr->vr->backend_drain;
shr->vr->backend_drain = NULL;
li_vrequest_connection_upgrade(shr->vr, backend_drain, &shr->stream);
li_stream_release(backend_drain);
}
return;
}

View File

@ -53,9 +53,9 @@ liVRequest* li_vrequest_new(liWorker *wrk, liConInfo *coninfo) {
void li_vrequest_free(liVRequest* vr) {
liServer *srv = vr->wrk->srv;
li_stream_safe_reset_and_release(&vr->backend_drain);
vr->direct_out = NULL;
li_stream_safe_reset_and_release(&vr->backend_source);
li_stream_safe_reset_and_release(&vr->backend_drain);
li_filter_buffer_on_disk_stop(vr->in_buffer_on_disk_stream);
li_stream_safe_reset_and_release(&vr->in_buffer_on_disk_stream);
@ -102,21 +102,9 @@ void li_vrequest_free(liVRequest* vr) {
void li_vrequest_reset(liVRequest *vr, gboolean keepalive) {
liServer *srv = vr->wrk->srv;
if (NULL != vr->backend_drain) {
li_stream_disconnect(vr->backend_drain);
li_stream_release(vr->backend_drain);
vr->backend_drain = NULL;
}
if (NULL != vr->backend_source) {
if (NULL == vr->backend_source->dest) {
/* wasn't connected: disconnect source */
li_stream_disconnect(vr->backend_source);
}
li_stream_disconnect_dest(vr->backend_source);
li_stream_release(vr->backend_source);
vr->backend_source = NULL;
vr->direct_out = NULL;
}
vr->direct_out = NULL;
li_stream_safe_reset_and_release(&vr->backend_source);
li_stream_safe_reset_and_release(&vr->backend_drain);
li_filter_buffer_on_disk_stop(vr->in_buffer_on_disk_stream);
li_stream_safe_reset_and_release(&vr->in_buffer_on_disk_stream);