Skip to content

Commit 02138ed

Browse files
rw_locking: add new primitives for lock acquiring/releasing required when switching from read to write access
Using the lock_start_read/lock_stop_read primitives would cause a deadlock if two or more readers would switch to writing
1 parent 881a382 commit 02138ed

File tree

1 file changed

+25
-1
lines changed

1 file changed

+25
-1
lines changed

rw_locking.h

+25-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
typedef struct rw_lock_t {
3131
gen_lock_t *lock;
3232
int w_flag;
33+
int sw_flag;
3334
int r_count;
3435
} rw_lock_t;
3536

@@ -113,7 +114,30 @@ inline static void lock_destroy_rw(rw_lock_t *_lock)
113114
lock_release((_lock)->lock); \
114115
} while (0)
115116

116-
/* switch to writing access with lock previously acquired for reading
117+
#define lock_start_sw_read(_lock) \
118+
do { \
119+
__label__ again; \
120+
again: \
121+
lock_get((_lock)->lock); \
122+
if ((_lock)->w_flag || (_lock)->sw_flag) { \
123+
lock_release((_lock)->lock); \
124+
usleep(LOCK_WAIT); \
125+
goto again; \
126+
} \
127+
(_lock)->r_count++; \
128+
(_lock)->sw_flag = 1; \
129+
lock_release((_lock)->lock); \
130+
} while (0)
131+
132+
#define lock_stop_sw_read(_lock) \
133+
do { \
134+
lock_get((_lock)->lock); \
135+
(_lock)->r_count--; \
136+
lock_release((_lock)->lock); \
137+
(_lock)->sw_flag = 0; \
138+
} while (0)
139+
140+
/* switch to writing access with lock previously acquired for switchable reading
117141
* note: switching back to reading is required before releasing the lock
118142
*/
119143
#define lock_switch_write(_lock, __old) \

0 commit comments

Comments
 (0)