-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrwlocker.c
80 lines (63 loc) · 1.76 KB
/
rwlocker.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include "rwlocker.h"
struct _RwLocker
{
int readers;
Emode mode;
Locker* rw_locker;
Locker* rd_locker;
};
RwLocker* rw_locker_create(Locker* rw_locker, Locker* rd_locker)
{
RwLocker* thiz = NULL;
return_val_if_fail(rw_locker != NULL && rd_locker != NULL, NULL);
thiz = (RwLocker*)malloc(sizeof(RwLocker));
if(thiz != NULL)
{
thiz->readers = 0;
thiz->mode = RW_LOCKER_NONE;
thiz->rw_locker = rw_locker;
thiz->rd_locker = rd_locker;
}
return thiz;
}
/*
写的时候不允许任何其它线程读或者写,读的时候允许其它线程读,但不允许其它线程写。所以在实现时,写的时候一定要加锁,第一个读的线程要加锁,后面其它线程读时,只是增加锁的引用计数。我们需要两个锁:一个锁用来保存被保护的对象,一个锁用来保护引用计数。
*/
Ret rw_locker_wrlock(RwLocker* thiz)
{
Ret ret = RET_OK;
return_val_if_fail(thiz != NULL, RET_INVALID_PARAMS);
if((ret = locker_lock(thiz->rw_locker)) == RET_OK)
{
thiz->mode = RW_LOCKER_WR;
}
return ret;
}
/*
加写锁很简单,直接加保护受保护对象的锁,然后修改锁的状态为已加写锁。后面其它的线程想写,就会这个锁上等待,如果想读也要等待
*/
Ret rw_locker_unlock(RwLocker* thiz)
{
Ret ret = RET_OK;
return_val_if_fail(thiz != NULL, RET_INVALID_PARAMS);
if(thiz->mode == RW_LOCKER_WR)
{
thiz->mode == RW_LOCKER_NONE;
ret = locker_unlock(thiz->rw_locker);
}
else
{
assert(thiz->mode == RW_LOCKER_RD);
if((ret = locker_lock(thiz->rd_locker)) == RET_OK)
{
thiz->readers--;
if(thiz->readers == 0)
{
thiz->mode == RW_LOCKER_NONE;
ret = locker_unlock(thiz->rw_locker);
}
locker_unlock(thiz->rd_locker);
}
}
return ret;
}