fellow: fini stevedore_priv / call fellow_busy_done() also for objfree

This bug was also present in varnish-cache (will document) and found
its way into fellow through the api-definition-by-example paradigm of
varnish-cache:

In varnish-cache vbf_stp_error(), an existing storage object is freed
to be replaced with a new one, potentially from a different storage
(usually -sTransient).

In this case, ObjBocDone is not called, because the boc is to be
preserved - from the client's perspective, the backend transaction is
still in progress, and the client is waiting for the busy object to
finish.

At the storage level, however, the process of creation of a new object
_is_ finished, and any busy object state which the storage might keep
needs to be finalized.

So, if oc->boc is not NULL for an ObjFreeObj() call, the stevedore
needs to finish any busy object transaction.

Fixes #14
parent 8ebb34f7
......@@ -339,8 +339,28 @@ stvfe_dskoc_fco(struct worker *wrk,
* obj_methods
*/
static void
sfemem_bocfini(struct boc *boc, struct objcore *oc, unsigned inlog)
{
struct fellow_busy *fbo;
CHECK_OBJ_NOTNULL(boc, BOC_MAGIC);
CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
fbo = boc->stevedore_priv;
AN(fbo);
boc->stevedore_priv = NULL;
fellow_busy_done(fbo, oc, inlog);
}
/* mem free */
/*
* called in two cases:
* - oc->boc == NULL: cache object on LRU freed
* - oc->boc != NULL: cache object replaced for backend error
*/
static void
sfemem_free(struct worker *wrk, struct objcore *memoc)
{
......@@ -354,7 +374,9 @@ sfemem_free(struct worker *wrk, struct objcore *memoc)
AN(stv->lru);
// ref fellow_busy_done()
if (memoc->boc == NULL)
if (memoc->boc != NULL)
sfemem_bocfini(memoc->boc, memoc, 0);
else
LRU_Remove(memoc);
if (stvfe->shutdown && wrk->strangelove == (int)STVELOVE_IS_DRAIN) {
......@@ -798,7 +820,6 @@ stvfe_oc_dle_submit(struct fellow_fd *ffd, struct objcore *oc,
static void v_matchproto_(objbocdone_f)
sfemem_bocdone(struct worker *wrk, struct objcore *oc, struct boc *boc)
{
struct fellow_busy *fbo;
unsigned inlog;
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
......@@ -806,16 +827,13 @@ sfemem_bocdone(struct worker *wrk, struct objcore *oc, struct boc *boc)
CHECK_OBJ_NOTNULL(boc, BOC_MAGIC);
// XXX can we sensibly avoid LRU_Add for !inlog?
LRU_Add(oc, VTIM_real());
if (oc->boc == NULL)
LRU_Add(oc, VTIM_real());
inlog = ! (/*lint --e(641,655)*/oc->flags &
(OC_F_PRIVATE|OC_F_DYING));
fbo = boc->stevedore_priv;
AN(fbo);
boc->stevedore_priv = NULL;
fellow_busy_done(fbo, oc, inlog);
sfemem_bocfini(boc, oc, inlog);
}
static const void * v_matchproto_(objgetattr_f)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment