Skip to content

Commit 818ca09

Browse files
cartoushnigoroll
authored andcommitted
vcp: Poll dying connection pools asynchronously
Before, we would wait in a blocking loop for connection pools to be freed before deleting them for good. This commit transforms this blocking loop into a CLI hook that will delete the freed connection pools at each trigger. Refs varnishcache#4064 Better diff with the --ignore-all-space option.
1 parent c412418 commit 818ca09

4 files changed

Lines changed: 77 additions & 11 deletions

File tree

bin/varnishd/cache/cache_cli.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ cli_cb_before(const struct cli *cli)
7878
VSL(SLT_CLI, NO_VXID, "Rd %s", VSB_data(cli->cmd));
7979
Lck_Lock(&cli_mtx);
8080
VCL_Poll();
81+
VCP_RelPoll();
8182
}
8283

8384
static void

bin/varnishd/cache/cache_conn_pool.c

Lines changed: 74 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -105,14 +105,20 @@ struct conn_pool {
105105
};
106106

107107
static struct lock conn_pools_mtx;
108+
static struct lock dead_pools_mtx;
108109

109-
static VRBT_HEAD(vrb, conn_pool) conn_pools = VRBT_INITIALIZER(&conn_pools);
110+
VRBT_HEAD(vrb, conn_pool);
110111
VRBT_GENERATE_REMOVE_COLOR(vrb, conn_pool, entry, static)
111112
VRBT_GENERATE_REMOVE(vrb, conn_pool, entry, static)
112113
VRBT_GENERATE_FIND(vrb, conn_pool, entry, vcp_cmp, static)
113114
VRBT_GENERATE_INSERT_COLOR(vrb, conn_pool, entry, static)
114115
VRBT_GENERATE_INSERT_FINISH(vrb, conn_pool, entry, static)
115116
VRBT_GENERATE_INSERT(vrb, conn_pool, entry, vcp_cmp, static)
117+
VRBT_GENERATE_NEXT(vrb, conn_pool, entry, static);
118+
VRBT_GENERATE_MINMAX(vrb, conn_pool, entry, static);
119+
120+
static struct vrb conn_pools = VRBT_INITIALIZER(&conn_pools);
121+
static struct vrb dead_pools = VRBT_INITIALIZER(&dying_cps);
116122

117123
/*--------------------------------------------------------------------
118124
*/
@@ -217,6 +223,22 @@ VCP_AddRef(struct conn_pool *cp)
217223
Lck_Unlock(&conn_pools_mtx);
218224
}
219225

226+
/*--------------------------------------------------------------------
227+
*/
228+
229+
static void
230+
vcp_destroy(struct conn_pool **cpp)
231+
{
232+
struct conn_pool *cp;
233+
234+
TAKE_OBJ_NOTNULL(cp, cpp, CONN_POOL_MAGIC);
235+
AZ(cp->n_conn);
236+
AZ(cp->n_kill);
237+
Lck_Delete(&cp->mtx);
238+
free(cp->endpoint);
239+
FREE_OBJ(cp);
240+
}
241+
220242
/*--------------------------------------------------------------------
221243
* Release Conn pool, destroy if last reference.
222244
*/
@@ -248,17 +270,57 @@ VCP_Rel(struct conn_pool **cpp)
248270
(void)shutdown(pfd->fd, SHUT_RDWR);
249271
cp->n_kill++;
250272
}
251-
while (cp->n_kill) {
252-
Lck_Unlock(&cp->mtx);
253-
(void)usleep(20000);
254-
Lck_Lock(&cp->mtx);
255-
}
256273
Lck_Unlock(&cp->mtx);
257-
Lck_Delete(&cp->mtx);
258-
AZ(cp->n_conn);
259-
AZ(cp->n_kill);
260-
free(cp->endpoint);
261-
FREE_OBJ(cp);
274+
if (cp->n_kill == 0) {
275+
vcp_destroy(&cp);
276+
return;
277+
}
278+
Lck_Lock(&dead_pools_mtx);
279+
/*
280+
* Here we reuse cp's entry but it will probably not be correctly
281+
* indexed because of the hack in VCP_RelPoll
282+
*/
283+
VRBT_INSERT(vrb, &dead_pools, cp);
284+
Lck_Unlock(&dead_pools_mtx);
285+
}
286+
287+
void
288+
VCP_RelPoll(void)
289+
{
290+
struct vrb dead;
291+
struct conn_pool *cp, *cp2;
292+
293+
ASSERT_CLI();
294+
295+
Lck_Lock(&dead_pools_mtx);
296+
if (VRBT_EMPTY(&dead_pools)) {
297+
Lck_Unlock(&dead_pools_mtx);
298+
return;
299+
}
300+
dead = dead_pools;
301+
VRBT_INIT(&dead_pools);
302+
Lck_Unlock(&dead_pools_mtx);
303+
304+
VRBT_FOREACH_SAFE(cp, vrb, &dead, cp2) {
305+
CHECK_OBJ_NOTNULL(cp, CONN_POOL_MAGIC);
306+
if (cp->n_kill > 0)
307+
continue;
308+
VRBT_REMOVE(vrb, &dead, cp);
309+
vcp_destroy(&cp);
310+
}
311+
312+
if (VRBT_EMPTY(&dead))
313+
return;
314+
315+
Lck_Lock(&dead_pools_mtx);
316+
/*
317+
* The following insertion will most likely result in an
318+
* unordered tree, but in this case it does not matter
319+
* as we just want to iterate over all the elements
320+
* in the tree in order to delete them.
321+
*/
322+
VRBT_INSERT(vrb, &dead_pools, dead.rbh_root);
323+
Lck_Unlock(&dead_pools_mtx);
262324
}
263325

264326
/*--------------------------------------------------------------------
@@ -582,6 +644,7 @@ void
582644
VCP_Init(void)
583645
{
584646
Lck_New(&conn_pools_mtx, lck_conn_pool);
647+
Lck_New(&dead_pools_mtx, lck_dead_pool);
585648
}
586649

587650
/**********************************************************************/

bin/varnishd/cache/cache_varnishd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,7 @@ void VSL_Flush(struct vsl_log *, int overflow);
472472
struct conn_pool;
473473
void VCP_Init(void);
474474
void VCP_Panic(struct vsb *, struct conn_pool *);
475+
void VCP_RelPoll(void);
475476

476477
/* cache_backend_probe.c */
477478
void VBP_Init(void);

include/tbl/locks.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ LOCK(pipestat)
4545
LOCK(probe)
4646
LOCK(sess)
4747
LOCK(conn_pool)
48+
LOCK(dead_pool)
4849
LOCK(vbe)
4950
LOCK(vcapace)
5051
LOCK(vcl)

0 commit comments

Comments
 (0)