1145519Sdarrenr/*	$FreeBSD$	*/
2145510Sdarrenr
3145510Sdarrenr/*
4255332Scy * Copyright (C) 2012 by Darren Reed.
5145510Sdarrenr *
6145510Sdarrenr * See the IPFILTER.LICENCE file for details on licencing.
7145510Sdarrenr *
8255332Scy * $Id$
9145510Sdarrenr */
10145510Sdarrenr
11145510Sdarrenr#include "ipf.h"
12145510Sdarrenr
13145510Sdarrenr#define	EMM_MAGIC	0x97dd8b3a
14145510Sdarrenr
15145510Sdarrenrvoid eMrwlock_read_enter(rw, file, line)
16145510Sdarrenr	eMrwlock_t *rw;
17145510Sdarrenr	char *file;
18255332Scy	int line;
19255332Scy{
20255332Scy	if (rw->eMrw_magic != EMM_MAGIC) {
21255332Scy		fprintf(stderr, "%s:eMrwlock_read_enter(%p): bad magic: %#x\n",
22255332Scy			rw->eMrw_owner, rw, rw->eMrw_magic);
23255332Scy		abort();
24145510Sdarrenr	}
25145510Sdarrenr	if (rw->eMrw_read != 0 || rw->eMrw_write != 0) {
26145510Sdarrenr		fprintf(stderr,
27145510Sdarrenr			"%s:eMrwlock_read_enter(%p): already locked: %d/%d\n",
28255332Scy			rw->eMrw_owner, rw, rw->eMrw_read, rw->eMrw_write);
29145510Sdarrenr		abort();
30145510Sdarrenr	}
31145510Sdarrenr	rw->eMrw_read++;
32145510Sdarrenr	rw->eMrw_heldin = file;
33145510Sdarrenr	rw->eMrw_heldat = line;
34145510Sdarrenr}
35145510Sdarrenr
36145510Sdarrenr
37145510Sdarrenrvoid eMrwlock_write_enter(rw, file, line)
38145510Sdarrenr	eMrwlock_t *rw;
39145510Sdarrenr	char *file;
40145510Sdarrenr	int line;
41145510Sdarrenr{
42145510Sdarrenr	if (rw->eMrw_magic != EMM_MAGIC) {
43145510Sdarrenr		fprintf(stderr, "%s:eMrwlock_write_enter(%p): bad magic: %#x\n",
44145510Sdarrenr			rw->eMrw_owner, rw, rw->eMrw_magic);
45145510Sdarrenr		abort();
46145510Sdarrenr	}
47145510Sdarrenr	if (rw->eMrw_read != 0 || rw->eMrw_write != 0) {
48145510Sdarrenr		fprintf(stderr,
49255332Scy			"%s:eMrwlock_write_enter(%p): already locked: %d/%d\n",
50145510Sdarrenr			rw->eMrw_owner, rw, rw->eMrw_read, rw->eMrw_write);
51255332Scy		abort();
52255332Scy	}
53145510Sdarrenr	rw->eMrw_write++;
54255332Scy	rw->eMrw_heldin = file;
55145510Sdarrenr	rw->eMrw_heldat = line;
56145510Sdarrenr}
57
58
59void eMrwlock_downgrade(rw, file, line)
60	eMrwlock_t *rw;
61	char *file;
62	int line;
63{
64	if (rw->eMrw_magic != EMM_MAGIC) {
65		fprintf(stderr, "%s:eMrwlock_write_enter(%p): bad magic: %#x\n",
66			rw->eMrw_owner, rw, rw->eMrw_magic);
67		abort();
68	}
69	if (rw->eMrw_read != 0 || rw->eMrw_write != 1) {
70		fprintf(stderr,
71			"%s:eMrwlock_write_enter(%p): already locked: %d/%d\n",
72			rw->eMrw_owner, rw, rw->eMrw_read, rw->eMrw_write);
73		abort();
74	}
75	rw->eMrw_write--;
76	rw->eMrw_read++;
77	rw->eMrw_heldin = file;
78	rw->eMrw_heldat = line;
79}
80
81
82void eMrwlock_exit(rw)
83	eMrwlock_t *rw;
84{
85	if (rw->eMrw_magic != EMM_MAGIC) {
86		fprintf(stderr, "%s:eMrwlock_exit(%p): bad magic: %#x\n",
87			rw->eMrw_owner, rw, rw->eMrw_magic);
88		abort();
89	}
90	if (rw->eMrw_read != 1 && rw->eMrw_write != 1) {
91		fprintf(stderr, "%s:eMrwlock_exit(%p): not locked: %d/%d\n",
92			rw->eMrw_owner, rw, rw->eMrw_read, rw->eMrw_write);
93		abort();
94	}
95	if (rw->eMrw_read == 1)
96		rw->eMrw_read--;
97	else if (rw->eMrw_write == 1)
98		rw->eMrw_write--;
99	rw->eMrw_heldin = NULL;
100	rw->eMrw_heldat = 0;
101}
102
103
104static int initcount = 0;
105
106void eMrwlock_init(rw, who)
107	eMrwlock_t *rw;
108	char *who;
109{
110	if (rw->eMrw_magic == EMM_MAGIC) {	/* safe bet ? */
111		fprintf(stderr,
112			"%s:eMrwlock_init(%p): already initialised?: %#x\n",
113			rw->eMrw_owner, rw, rw->eMrw_magic);
114		abort();
115	}
116	rw->eMrw_magic = EMM_MAGIC;
117	rw->eMrw_read = 0;
118	rw->eMrw_write = 0;
119	if (who != NULL)
120		rw->eMrw_owner = strdup(who);
121	else
122		rw->eMrw_owner = NULL;
123	initcount++;
124}
125
126
127void eMrwlock_destroy(rw)
128	eMrwlock_t *rw;
129{
130	if (rw->eMrw_magic != EMM_MAGIC) {
131		fprintf(stderr, "%s:eMrwlock_destroy(%p): bad magic: %#x\n",
132			rw->eMrw_owner, rw, rw->eMrw_magic);
133		abort();
134	}
135	if (rw->eMrw_owner != NULL)
136		free(rw->eMrw_owner);
137	memset(rw, 0xa5, sizeof(*rw));
138	initcount--;
139}
140
141void ipf_rwlock_clean()
142{
143	if (initcount != 0)
144		abort();
145}
146