Do not unlock upstream without referencing its dying ops

This commit is contained in:
Ondřej Kuzník 2018-03-20 17:25:11 +00:00
parent b1c098ad76
commit 1ea5ee1f01
2 changed files with 10 additions and 7 deletions

View file

@ -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);

View file

@ -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 );