From: phk Date: Mon, 10 Nov 2008 19:48:08 +0000 (+0000) Subject: Remember to add this file in second attempt :-) X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=18fa49f7baf4300083d28af94fb944006ddfb07a;p=varnish Remember to add this file in second attempt :-) git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@3382 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- diff --git a/varnish-cache/bin/varnishd/cache_lck.c b/varnish-cache/bin/varnishd/cache_lck.c new file mode 100644 index 00000000..11b010ba --- /dev/null +++ b/varnish-cache/bin/varnishd/cache_lck.c @@ -0,0 +1,183 @@ +/*- + * Copyright (c) 2008 Linpro AS + * All rights reserved. + * + * Author: Poul-Henning Kamp + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + * + * The geniuses who came up with pthreads did not think operations like + * pthread_assert_mutex_held() were important enough to include them in + * the API. + * + * Build our own locks on top of pthread mutexes and hope that the next + * civilization is better at such crucial details than this one. + */ + +#include "config.h" + +#include + +#include +#ifdef HAVE_PTHREAD_NP_H +#include +#endif +#include + +#include "shmlog.h" +#include "cache.h" + +struct ilck { + unsigned magic; +#define ILCK_MAGIC 0x7b86c8a5 + pthread_mutex_t mtx; + pthread_t owner; + VTAILQ_ENTRY(ilck) list; + const char *w; +}; + +static VTAILQ_HEAD(, ilck) ilck_head = + VTAILQ_HEAD_INITIALIZER(ilck_head); + +static pthread_mutex_t lck_mtx; + +void +Lck__Lock(struct lock *lck, const char *p, const char *f, int l) +{ + struct ilck *ilck; + int r; + + CAST_OBJ_NOTNULL(ilck, lck->priv, ILCK_MAGIC); + if (!(params->diag_bitmap & 0x18)) { + AZ(pthread_mutex_lock(&ilck->mtx)); + AZ(ilck->owner); + ilck->owner = pthread_self(); + return; + } + r = pthread_mutex_trylock(&ilck->mtx); + assert(r == 0 || errno == EBUSY); + if (r) { + VSL(SLT_Debug, 0, "MTX_CONTEST(%s,%s,%d,%s)", p, f, l, ilck->w); + AZ(pthread_mutex_lock(&ilck->mtx)); + } else if (params->diag_bitmap & 0x8) { + VSL(SLT_Debug, 0, "MTX_LOCK(%s,%s,%d,%s)", p, f, l, ilck->w); + } + AZ(ilck->owner); + ilck->owner = pthread_self(); +} + +void +Lck__Unlock(struct lock *lck, const char *p, const char *f, int l) +{ + struct ilck *ilck; + + CAST_OBJ_NOTNULL(ilck, lck->priv, ILCK_MAGIC); + assert(ilck->owner == pthread_self()); + ilck->owner = NULL; + AZ(pthread_mutex_unlock(&ilck->mtx)); + if (params->diag_bitmap & 0x8) + VSL(SLT_Debug, 0, "MTX_UNLOCK(%s,%s,%d,%s)", p, f, l, ilck->w); +} + +int +Lck__Trylock(struct lock *lck, const char *p, const char *f, int l) +{ + struct ilck *ilck; + int r; + + CAST_OBJ_NOTNULL(ilck, lck->priv, ILCK_MAGIC); + r = pthread_mutex_lock(&ilck->mtx); + assert(r == 0 || errno == EBUSY); + if (params->diag_bitmap & 0x8) + VSL(SLT_Debug, 0, + "MTX_TRYLOCK(%s,%s,%d,%s) = %d", p, f, l, ilck->w); + if (r == 0) { + AZ(ilck->owner); + ilck->owner = pthread_self(); + } + return (r); +} + +void +Lck__Assert(struct lock *lck, int held) +{ + struct ilck *ilck; + + CAST_OBJ_NOTNULL(ilck, lck->priv, ILCK_MAGIC); + if (held) + assert(ilck->owner == pthread_self()); + else + assert(ilck->owner != pthread_self()); +} + +void +Lck_CondWait(pthread_cond_t *cond, struct lock *lck) +{ + struct ilck *ilck; + + CAST_OBJ_NOTNULL(ilck, lck->priv, ILCK_MAGIC); + assert(ilck->owner == pthread_self()); + ilck->owner = NULL; + AZ(pthread_cond_wait(cond, &ilck->mtx)); + AZ(ilck->owner); + ilck->owner = pthread_self(); +} + +void +Lck__New(struct lock *lck, const char *w) +{ + struct ilck *ilck; + + AZ(lck->priv); + ALLOC_OBJ(ilck, ILCK_MAGIC); + AN(ilck); + ilck->w = w; + AZ(pthread_mutex_init(&ilck->mtx, NULL)); + AZ(pthread_mutex_lock(&lck_mtx)); + VTAILQ_INSERT_TAIL(&ilck_head, ilck, list); + AZ(pthread_mutex_unlock(&lck_mtx)); + lck->priv = ilck; +} + +void +Lck_Delete(struct lock *lck) +{ + struct ilck *ilck; + + CAST_OBJ_NOTNULL(ilck, lck->priv, ILCK_MAGIC); + lck->priv = NULL; + AZ(pthread_mutex_lock(&lck_mtx)); + VTAILQ_REMOVE(&ilck_head, ilck, list); + AZ(pthread_mutex_unlock(&lck_mtx)); + AZ(pthread_mutex_destroy(&ilck->mtx)); + FREE_OBJ(ilck); +} + + +void +LCK_Init(void) +{ + + AZ(pthread_mutex_init(&lck_mtx, NULL)); +}