[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