[master] 7f017eb Atomically grab the busyobj, if there is one.
Poul-Henning Kamp
phk at varnish-cache.org
Fri Sep 6 23:50:45 CEST 2013
commit 7f017ebe826be6b435e98762bd32ee56191cb6fb
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Fri Sep 6 20:31:17 2013 +0000
Atomically grab the busyobj, if there is one.
diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index cc2f963..b0747cc 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -1060,7 +1060,7 @@ void *MPL_Get(struct mempool *mpl, unsigned *size);
void MPL_Free(struct mempool *mpl, void *item);
/* cache_obj.c */
-struct objiter *ObjIterBegin(struct object *);
+struct objiter *ObjIterBegin(struct worker *, struct object *);
int ObjIter(struct objiter *, void **, ssize_t *);
void ObjIterEnd(struct objiter **);
diff --git a/bin/varnishd/cache/cache_hash.c b/bin/varnishd/cache/cache_hash.c
index 46ec3ba..7171b53 100644
--- a/bin/varnishd/cache/cache_hash.c
+++ b/bin/varnishd/cache/cache_hash.c
@@ -712,6 +712,29 @@ HSH_Ref(struct objcore *oc)
Lck_Unlock(&oh->mtx);
}
+/*---------------------------------------------------------------------
+ * Gain a reference on the busyobj, if the objcore has one
+ */
+
+struct busyobj *
+HSH_RefBusy(const struct objcore *oc)
+{
+ struct objhead *oh;
+ struct busyobj *bo;
+
+ CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
+ oh = oc->objhead;
+ CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
+ Lck_Lock(&oh->mtx);
+ assert(oc->refcnt > 0);
+ bo = oc->busyobj;
+ CHECK_OBJ_ORNULL(bo, BUSYOBJ_MAGIC);
+ if (bo != NULL)
+ bo->refcount++;
+ Lck_Unlock(&oh->mtx);
+ return (bo);
+}
+
/*--------------------------------------------------------------------
* Dereference objcore and or object
*
diff --git a/bin/varnishd/cache/cache_http1_deliver.c b/bin/varnishd/cache/cache_http1_deliver.c
index 640d94a..1678eb5 100644
--- a/bin/varnishd/cache/cache_http1_deliver.c
+++ b/bin/varnishd/cache/cache_http1_deliver.c
@@ -164,7 +164,7 @@ v1d_WriteDirObj(struct req *req)
CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
- oi = ObjIterBegin(req->obj);
+ oi = ObjIterBegin(req->wrk, req->obj);
XXXAN(oi);
while (ObjIter(oi, &ptr, &len)) {
diff --git a/bin/varnishd/cache/cache_obj.c b/bin/varnishd/cache/cache_obj.c
index 5b878b9..3db119d 100644
--- a/bin/varnishd/cache/cache_obj.c
+++ b/bin/varnishd/cache/cache_obj.c
@@ -31,25 +31,31 @@
#include <stdlib.h>
#include "cache.h"
+#include "hash/hash_slinger.h"
struct objiter {
unsigned magic;
#define OBJITER_MAGIC 0x745fb151
+ struct busyobj *bo;
struct object *obj;
struct storage *st;
+ struct worker *wrk;
};
struct objiter *
-ObjIterBegin(struct object *obj)
+ObjIterBegin(struct worker *wrk, struct object *obj)
{
struct objiter *oi;
CHECK_OBJ_NOTNULL(obj, OBJECT_MAGIC);
ALLOC_OBJ(oi, OBJITER_MAGIC);
+ if (oi == NULL)
+ return (oi);
+ oi->obj = obj;
+ oi->wrk = wrk;
+ oi->bo = HSH_RefBusy(obj->objcore);
while (obj->objcore->busyobj != NULL)
- usleep(10000);
- if (oi != NULL)
- oi->obj = obj;
+ (void)usleep(10000);
return (oi);
}
@@ -77,6 +83,10 @@ void
ObjIterEnd(struct objiter **oi)
{
+ AN(oi);
CHECK_OBJ_NOTNULL((*oi), OBJITER_MAGIC);
+ if ((*oi)->bo != NULL)
+ VBO_DerefBusyObj((*oi)->wrk, &(*oi)->bo);
FREE_OBJ((*oi));
+ *oi = NULL;
}
diff --git a/bin/varnishd/hash/hash_slinger.h b/bin/varnishd/hash/hash_slinger.h
index 152eebd..cbe7082 100644
--- a/bin/varnishd/hash/hash_slinger.h
+++ b/bin/varnishd/hash/hash_slinger.h
@@ -73,6 +73,7 @@ void HSH_AddString(const struct req *, const char *str);
void HSH_Insert(struct worker *, const void *hash, struct objcore *);
void HSH_Purge(struct worker *, struct objhead *, double ttl, double grace);
void HSH_config(const char *h_arg);
+struct busyobj *HSH_RefBusy(const struct objcore *oc);
struct objcore *HSH_Private(struct worker *wrk);
struct objcore *HSH_NewObjCore(struct worker *wrk);
More information about the varnish-commit
mailing list