Commit abf5aec4 authored by Geoff Simmons's avatar Geoff Simmons

protect access to the backend list with a rwlock (per VCL)

parent 7980ea42
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <netdb.h> #include <netdb.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <pthread.h>
#include "vcl.h" #include "vcl.h"
#include "vrt.h" #include "vrt.h"
...@@ -60,6 +61,7 @@ struct belist { ...@@ -60,6 +61,7 @@ struct belist {
unsigned magic; unsigned magic;
#define BELIST_MAGIC 0x66d0afdb #define BELIST_MAGIC 0x66d0afdb
VTAILQ_HEAD(behead, bentry) *behead; VTAILQ_HEAD(behead, bentry) *behead;
pthread_rwlock_t lock;
}; };
static void static void
...@@ -71,6 +73,7 @@ free_belist(void *priv) ...@@ -71,6 +73,7 @@ free_belist(void *priv)
if (priv == NULL) if (priv == NULL)
return; return;
CAST_OBJ(belist, priv, BELIST_MAGIC); CAST_OBJ(belist, priv, BELIST_MAGIC);
AZ(pthread_rwlock_destroy(&belist->lock));
AN(belist->behead); AN(belist->behead);
bentry = VTAILQ_FIRST(belist->behead); bentry = VTAILQ_FIRST(belist->behead);
while (bentry != NULL) { while (bentry != NULL) {
...@@ -176,22 +179,31 @@ vmod_create(VRT_CTX, struct vmod_priv *priv, VCL_STRING vcl_name, ...@@ -176,22 +179,31 @@ vmod_create(VRT_CTX, struct vmod_priv *priv, VCL_STRING vcl_name,
if (priv->priv == NULL) { if (priv->priv == NULL) {
ALLOC_OBJ(belist, BELIST_MAGIC); ALLOC_OBJ(belist, BELIST_MAGIC);
AN(belist); AN(belist);
AZ(pthread_rwlock_init(&belist->lock, NULL));
belist->behead = malloc(sizeof(belist->behead)); belist->behead = malloc(sizeof(belist->behead));
AN(belist->behead);
VTAILQ_INIT(belist->behead); VTAILQ_INIT(belist->behead);
priv->priv = belist; priv->priv = belist;
priv->free = free_belist; priv->free = free_belist;
} }
else { else {
int redefined = 0;
CAST_OBJ(belist, priv->priv, BELIST_MAGIC); CAST_OBJ(belist, priv->priv, BELIST_MAGIC);
AN(belist->behead); AN(belist->behead);
AZ(pthread_rwlock_rdlock(&belist->lock));
VTAILQ_FOREACH(bentry, belist->behead, bentry) { VTAILQ_FOREACH(bentry, belist->behead, bentry) {
CHECK_OBJ_NOTNULL(bentry, BENTRY_MAGIC); CHECK_OBJ_NOTNULL(bentry, BENTRY_MAGIC);
CHECK_OBJ_NOTNULL(bentry->be, DIRECTOR_MAGIC); CHECK_OBJ_NOTNULL(bentry->be, DIRECTOR_MAGIC);
if (strcmp(bentry->be->vcl_name, vcl_name) == 0) { if (strcmp(bentry->be->vcl_name, vcl_name) == 0) {
errmsg(ctx, "Backend %s redefined", vcl_name); redefined = 1;
return 0; break;
} }
} }
AZ(pthread_rwlock_unlock(&belist->lock));
if (redefined) {
errmsg(ctx, "Backend %s redefined", vcl_name);
return 0;
}
} }
sa4 = get_suckaddr(host, port, AF_INET); sa4 = get_suckaddr(host, port, AF_INET);
...@@ -226,7 +238,9 @@ vmod_create(VRT_CTX, struct vmod_priv *priv, VCL_STRING vcl_name, ...@@ -226,7 +238,9 @@ vmod_create(VRT_CTX, struct vmod_priv *priv, VCL_STRING vcl_name,
ALLOC_OBJ(bentry, BENTRY_MAGIC); ALLOC_OBJ(bentry, BENTRY_MAGIC);
AN(bentry); AN(bentry);
bentry->be = dir; bentry->be = dir;
AZ(pthread_rwlock_wrlock(&belist->lock));
VTAILQ_INSERT_HEAD(belist->behead, bentry, bentry); VTAILQ_INSERT_HEAD(belist->behead, bentry, bentry);
AZ(pthread_rwlock_unlock(&belist->lock));
return 1; return 1;
} }
...@@ -235,6 +249,7 @@ vmod_by_name(VRT_CTX, struct vmod_priv *priv, VCL_STRING name) ...@@ -235,6 +249,7 @@ vmod_by_name(VRT_CTX, struct vmod_priv *priv, VCL_STRING name)
{ {
struct belist *belist; struct belist *belist;
struct bentry *bentry; struct bentry *bentry;
const struct director *dir = NULL;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
AN(priv); AN(priv);
...@@ -244,13 +259,17 @@ vmod_by_name(VRT_CTX, struct vmod_priv *priv, VCL_STRING name) ...@@ -244,13 +259,17 @@ vmod_by_name(VRT_CTX, struct vmod_priv *priv, VCL_STRING name)
return NULL; return NULL;
CAST_OBJ_NOTNULL(belist, priv->priv, BELIST_MAGIC); CAST_OBJ_NOTNULL(belist, priv->priv, BELIST_MAGIC);
AN(belist->behead); AN(belist->behead);
AZ(pthread_rwlock_rdlock(&belist->lock));
VTAILQ_FOREACH(bentry, belist->behead, bentry) { VTAILQ_FOREACH(bentry, belist->behead, bentry) {
CHECK_OBJ_NOTNULL(bentry, BENTRY_MAGIC); CHECK_OBJ_NOTNULL(bentry, BENTRY_MAGIC);
CHECK_OBJ_NOTNULL(bentry->be, DIRECTOR_MAGIC); CHECK_OBJ_NOTNULL(bentry->be, DIRECTOR_MAGIC);
if (strcmp(name, bentry->be->vcl_name) == 0) if (strcmp(name, bentry->be->vcl_name) == 0) {
return bentry->be; dir = bentry->be;
break;
}
} }
return NULL; AZ(pthread_rwlock_unlock(&belist->lock));
return dir;
} }
VCL_BOOL VCL_BOOL
...@@ -270,6 +289,7 @@ vmod_delete(VRT_CTX, struct vmod_priv *priv, VCL_BACKEND be) ...@@ -270,6 +289,7 @@ vmod_delete(VRT_CTX, struct vmod_priv *priv, VCL_BACKEND be)
CAST_OBJ(belist, priv->priv, BELIST_MAGIC); CAST_OBJ(belist, priv->priv, BELIST_MAGIC);
AN(belist->behead); AN(belist->behead);
AZ(pthread_rwlock_wrlock(&belist->lock));
VTAILQ_FOREACH(bentry, belist->behead, bentry) { VTAILQ_FOREACH(bentry, belist->behead, bentry) {
CHECK_OBJ_NOTNULL(bentry, BENTRY_MAGIC); CHECK_OBJ_NOTNULL(bentry, BENTRY_MAGIC);
CHECK_OBJ_NOTNULL(bentry->be, DIRECTOR_MAGIC); CHECK_OBJ_NOTNULL(bentry->be, DIRECTOR_MAGIC);
...@@ -279,6 +299,7 @@ vmod_delete(VRT_CTX, struct vmod_priv *priv, VCL_BACKEND be) ...@@ -279,6 +299,7 @@ vmod_delete(VRT_CTX, struct vmod_priv *priv, VCL_BACKEND be)
break; break;
} }
} }
AZ(pthread_rwlock_unlock(&belist->lock));
if (dir == NULL) if (dir == NULL)
return 0; return 0;
VRT_delete_backend(ctx, &dir); VRT_delete_backend(ctx, &dir);
......
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