xref: /freebsd/sbin/ipf/libipf/rwlock_emul.c (revision 2a63c3be)
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)14efeb8bffSCy 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)33efeb8bffSCy 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)52efeb8bffSCy 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)70efeb8bffSCy 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)90efeb8bffSCy 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)113efeb8bffSCy 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)132efeb8bffSCy 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)145efeb8bffSCy Schubert void ipf_rwlock_clean(void)
14641edb306SCy Schubert {
14741edb306SCy Schubert 	if (initcount != 0)
14841edb306SCy Schubert 		abort();
14941edb306SCy Schubert }
150