141edb306SCy Schubert
241edb306SCy Schubert /*
341edb306SCy Schubert * Copyright (C) 2012 by Darren Reed.
441edb306SCy Schubert *
541edb306SCy Schubert * See the IPFILTER.LICENCE file for details on licencing.
641edb306SCy Schubert *
741edb306SCy Schubert * $Id$
841edb306SCy Schubert */
941edb306SCy Schubert
1041edb306SCy Schubert #include "ipf.h"
1141edb306SCy Schubert
1241edb306SCy Schubert #define EMM_MAGIC 0x97dd8b3a
1341edb306SCy Schubert
eMrwlock_read_enter(eMrwlock_t * rw,char * file,int line)14*efeb8bffSCy Schubert void eMrwlock_read_enter(eMrwlock_t *rw, char *file, int line)
1541edb306SCy Schubert {
1641edb306SCy Schubert if (rw->eMrw_magic != EMM_MAGIC) {
1741edb306SCy Schubert fprintf(stderr, "%s:eMrwlock_read_enter(%p): bad magic: %#x\n",
1841edb306SCy Schubert rw->eMrw_owner, rw, rw->eMrw_magic);
1941edb306SCy Schubert abort();
2041edb306SCy Schubert }
2141edb306SCy Schubert if (rw->eMrw_read != 0 || rw->eMrw_write != 0) {
2241edb306SCy Schubert fprintf(stderr,
2341edb306SCy Schubert "%s:eMrwlock_read_enter(%p): already locked: %d/%d\n",
2441edb306SCy Schubert rw->eMrw_owner, rw, rw->eMrw_read, rw->eMrw_write);
2541edb306SCy Schubert abort();
2641edb306SCy Schubert }
2741edb306SCy Schubert rw->eMrw_read++;
2841edb306SCy Schubert rw->eMrw_heldin = file;
2941edb306SCy Schubert rw->eMrw_heldat = line;
3041edb306SCy Schubert }
3141edb306SCy Schubert
3241edb306SCy Schubert
eMrwlock_write_enter(eMrwlock_t * rw,char * file,int line)33*efeb8bffSCy Schubert void eMrwlock_write_enter(eMrwlock_t *rw, char *file, int line)
3441edb306SCy Schubert {
3541edb306SCy Schubert if (rw->eMrw_magic != EMM_MAGIC) {
3641edb306SCy Schubert fprintf(stderr, "%s:eMrwlock_write_enter(%p): bad magic: %#x\n",
3741edb306SCy Schubert rw->eMrw_owner, rw, rw->eMrw_magic);
3841edb306SCy Schubert abort();
3941edb306SCy Schubert }
4041edb306SCy Schubert if (rw->eMrw_read != 0 || rw->eMrw_write != 0) {
4141edb306SCy Schubert fprintf(stderr,
4241edb306SCy Schubert "%s:eMrwlock_write_enter(%p): already locked: %d/%d\n",
4341edb306SCy Schubert rw->eMrw_owner, rw, rw->eMrw_read, rw->eMrw_write);
4441edb306SCy Schubert abort();
4541edb306SCy Schubert }
4641edb306SCy Schubert rw->eMrw_write++;
4741edb306SCy Schubert rw->eMrw_heldin = file;
4841edb306SCy Schubert rw->eMrw_heldat = line;
4941edb306SCy Schubert }
5041edb306SCy Schubert
5141edb306SCy Schubert
eMrwlock_try_upgrade(eMrwlock_t * rw,char * file,int line)52*efeb8bffSCy Schubert void eMrwlock_try_upgrade(eMrwlock_t *rw, char *file, int line)
5341edb306SCy Schubert {
5441edb306SCy Schubert if (rw->eMrw_magic != EMM_MAGIC) {
5541edb306SCy Schubert fprintf(stderr, "%s:eMrwlock_write_enter(%p): bad magic: %#x\n",
5641edb306SCy Schubert rw->eMrw_owner, rw, rw->eMrw_magic);
5741edb306SCy Schubert abort();
5841edb306SCy Schubert }
5941edb306SCy Schubert if (rw->eMrw_read != 0 || rw->eMrw_write != 0) {
6041edb306SCy Schubert fprintf(stderr,
6141edb306SCy Schubert "%s:eMrwlock_try_upgrade(%p): already locked: %d/%d\n",
6241edb306SCy Schubert rw->eMrw_owner, rw, rw->eMrw_read, rw->eMrw_write);
6341edb306SCy Schubert abort();
6441edb306SCy Schubert }
6541edb306SCy Schubert rw->eMrw_write++;
6641edb306SCy Schubert rw->eMrw_heldin = file;
6741edb306SCy Schubert rw->eMrw_heldat = line;
6841edb306SCy Schubert }
6941edb306SCy Schubert
eMrwlock_downgrade(eMrwlock_t * rw,char * file,int line)70*efeb8bffSCy Schubert void eMrwlock_downgrade(eMrwlock_t *rw, char *file, int line)
7141edb306SCy Schubert {
7241edb306SCy Schubert if (rw->eMrw_magic != EMM_MAGIC) {
7341edb306SCy Schubert fprintf(stderr, "%s:eMrwlock_write_enter(%p): bad magic: %#x\n",
7441edb306SCy Schubert rw->eMrw_owner, rw, rw->eMrw_magic);
7541edb306SCy Schubert abort();
7641edb306SCy Schubert }
7741edb306SCy Schubert if (rw->eMrw_read != 0 || rw->eMrw_write != 1) {
7841edb306SCy Schubert fprintf(stderr,
7941edb306SCy Schubert "%s:eMrwlock_write_enter(%p): already locked: %d/%d\n",
8041edb306SCy Schubert rw->eMrw_owner, rw, rw->eMrw_read, rw->eMrw_write);
8141edb306SCy Schubert abort();
8241edb306SCy Schubert }
8341edb306SCy Schubert rw->eMrw_write--;
8441edb306SCy Schubert rw->eMrw_read++;
8541edb306SCy Schubert rw->eMrw_heldin = file;
8641edb306SCy Schubert rw->eMrw_heldat = line;
8741edb306SCy Schubert }
8841edb306SCy Schubert
8941edb306SCy Schubert
eMrwlock_exit(eMrwlock_t * rw)90*efeb8bffSCy Schubert void eMrwlock_exit(eMrwlock_t *rw)
9141edb306SCy Schubert {
9241edb306SCy Schubert if (rw->eMrw_magic != EMM_MAGIC) {
9341edb306SCy Schubert fprintf(stderr, "%s:eMrwlock_exit(%p): bad magic: %#x\n",
9441edb306SCy Schubert rw->eMrw_owner, rw, rw->eMrw_magic);
9541edb306SCy Schubert abort();
9641edb306SCy Schubert }
9741edb306SCy Schubert if (rw->eMrw_read != 1 && rw->eMrw_write != 1) {
9841edb306SCy Schubert fprintf(stderr, "%s:eMrwlock_exit(%p): not locked: %d/%d\n",
9941edb306SCy Schubert rw->eMrw_owner, rw, rw->eMrw_read, rw->eMrw_write);
10041edb306SCy Schubert abort();
10141edb306SCy Schubert }
10241edb306SCy Schubert if (rw->eMrw_read == 1)
10341edb306SCy Schubert rw->eMrw_read--;
10441edb306SCy Schubert else if (rw->eMrw_write == 1)
10541edb306SCy Schubert rw->eMrw_write--;
10641edb306SCy Schubert rw->eMrw_heldin = NULL;
10741edb306SCy Schubert rw->eMrw_heldat = 0;
10841edb306SCy Schubert }
10941edb306SCy Schubert
11041edb306SCy Schubert
11141edb306SCy Schubert static int initcount = 0;
11241edb306SCy Schubert
eMrwlock_init(eMrwlock_t * rw,char * who)113*efeb8bffSCy Schubert void eMrwlock_init(eMrwlock_t *rw, char *who)
11441edb306SCy Schubert {
11541edb306SCy Schubert if (rw->eMrw_magic == EMM_MAGIC) { /* safe bet ? */
11641edb306SCy Schubert fprintf(stderr,
11741edb306SCy Schubert "%s:eMrwlock_init(%p): already initialised?: %#x\n",
11841edb306SCy Schubert rw->eMrw_owner, rw, rw->eMrw_magic);
11941edb306SCy Schubert abort();
12041edb306SCy Schubert }
12141edb306SCy Schubert rw->eMrw_magic = EMM_MAGIC;
12241edb306SCy Schubert rw->eMrw_read = 0;
12341edb306SCy Schubert rw->eMrw_write = 0;
12441edb306SCy Schubert if (who != NULL)
12541edb306SCy Schubert rw->eMrw_owner = strdup(who);
12641edb306SCy Schubert else
12741edb306SCy Schubert rw->eMrw_owner = NULL;
12841edb306SCy Schubert initcount++;
12941edb306SCy Schubert }
13041edb306SCy Schubert
13141edb306SCy Schubert
eMrwlock_destroy(eMrwlock_t * rw)132*efeb8bffSCy Schubert void eMrwlock_destroy(eMrwlock_t *rw)
13341edb306SCy Schubert {
13441edb306SCy Schubert if (rw->eMrw_magic != EMM_MAGIC) {
13541edb306SCy Schubert fprintf(stderr, "%s:eMrwlock_destroy(%p): bad magic: %#x\n",
13641edb306SCy Schubert rw->eMrw_owner, rw, rw->eMrw_magic);
13741edb306SCy Schubert abort();
13841edb306SCy Schubert }
13941edb306SCy Schubert if (rw->eMrw_owner != NULL)
14041edb306SCy Schubert free(rw->eMrw_owner);
14141edb306SCy Schubert memset(rw, 0xa5, sizeof(*rw));
14241edb306SCy Schubert initcount--;
14341edb306SCy Schubert }
14441edb306SCy Schubert
ipf_rwlock_clean(void)145*efeb8bffSCy Schubert void ipf_rwlock_clean(void)
14641edb306SCy Schubert {
14741edb306SCy Schubert if (initcount != 0)
14841edb306SCy Schubert abort();
14941edb306SCy Schubert }
150