From 1ea5ee1f01df40595a471d01370ed0b30340b2c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Kuzn=C3=ADk?= Date: Tue, 20 Mar 2018 17:25:11 +0000 Subject: [PATCH] Do not unlock upstream without referencing its dying ops --- servers/lloadd/operation.c | 7 +------ servers/lloadd/upstream.c | 10 +++++++++- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/servers/lloadd/operation.c b/servers/lloadd/operation.c index efd2531a5a..c9e69cd94d 100644 --- a/servers/lloadd/operation.c +++ b/servers/lloadd/operation.c @@ -806,16 +806,11 @@ void operation_lost_upstream( LloadOperation *op ) { LloadConnection *c = op->o_upstream; - CONNECTION_LOCK(c); - op->o_res = LLOAD_OP_FAILED; - op->o_upstream_refcnt++; - /* Matching the op reference on the connection as well */ - CONNECTION_UNLOCK_INCREF(c); operation_send_reject( op, LDAP_UNAVAILABLE, "connection to the remote server has been severed", 0 ); - CONNECTION_LOCK_DECREF(c); + CONNECTION_LOCK(c); op->o_upstream_refcnt--; operation_destroy_from_upstream( op ); CONNECTION_UNLOCK(c); diff --git a/servers/lloadd/upstream.c b/servers/lloadd/upstream.c index a1d17ab9bf..391b609108 100644 --- a/servers/lloadd/upstream.c +++ b/servers/lloadd/upstream.c @@ -760,7 +760,7 @@ upstream_destroy( LloadConnection *c ) { LloadBackend *b = c->c_private; struct event *read_event, *write_event; - TAvlnode *root; + TAvlnode *root, *node; long freed, executing; enum sc_state state; @@ -780,6 +780,14 @@ upstream_destroy( LloadConnection *c ) read_event = c->c_read_event; write_event = c->c_write_event; + for ( node = tavl_end( root, TAVL_DIR_LEFT ); node; + node = tavl_next( node, TAVL_DIR_RIGHT ) ) { + LloadOperation *op = node->avl_data; + + op->o_res = LLOAD_OP_FAILED; + op->o_upstream_refcnt++; + } + CONNECTION_UNLOCK_INCREF(c); freed = tavl_free( root, (AVL_FREE)operation_lost_upstream );