Annotation of embedaddon/strongswan/src/libstrongswan/threading/windows/mutex.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2013 Martin Willi
3: * Copyright (C) 2013 revosec AG
4: *
5: * This program is free software; you can redistribute it and/or modify it
6: * under the terms of the GNU General Public License as published by the
7: * Free Software Foundation; either version 2 of the License, or (at your
8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9: *
10: * This program is distributed in the hope that it will be useful, but
11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13: * for more details.
14: */
15:
16: #include "thread.h"
17:
18: #include <utils/debug.h>
19: #include <threading/mutex.h>
20: #include <threading/condvar.h>
21:
22: typedef struct private_mutex_t private_mutex_t;
23: typedef struct private_condvar_t private_condvar_t;
24:
25: /**
26: * private data of mutex
27: */
28: struct private_mutex_t {
29:
30: /**
31: * public functions
32: */
33: mutex_t public;
34:
35: /**
36: * wrapped critical section
37: */
38: CRITICAL_SECTION cs;
39:
40: /**
41: * Recursive lock count
42: */
43: u_int times;
44: };
45:
46: /**
47: * private data of condvar
48: */
49: struct private_condvar_t {
50:
51: /**
52: * public functions
53: */
54: condvar_t public;
55:
56: /**
57: * wrapped condition variable
58: */
59: CONDITION_VARIABLE cv;
60: };
61:
62:
63: METHOD(mutex_t, lock, void,
64: private_mutex_t *this)
65: {
66: EnterCriticalSection(&this->cs);
67: this->times++;
68: }
69:
70: METHOD(mutex_t, unlock, void,
71: private_mutex_t *this)
72: {
73: this->times--;
74: LeaveCriticalSection(&this->cs);
75: }
76:
77: METHOD(mutex_t, mutex_destroy, void,
78: private_mutex_t *this)
79: {
80: DeleteCriticalSection(&this->cs);
81: free(this);
82: }
83:
84: /*
85: * see header file
86: */
87: mutex_t *mutex_create(mutex_type_t type)
88: {
89: private_mutex_t *this;
90:
91: INIT(this,
92: .public = {
93: .lock = _lock,
94: .unlock = _unlock,
95: .destroy = _mutex_destroy,
96: },
97: );
98:
99: /* CriticalSections are recursive, we use it for all mutex types. */
100: InitializeCriticalSection(&this->cs);
101:
102: return &this->public;
103: }
104:
105: METHOD(condvar_t, timed_wait, bool,
106: private_condvar_t *this, mutex_t *pubmutex, u_int timeout)
107: {
108: private_mutex_t *mutex = (private_mutex_t*)pubmutex;
109: u_int times;
110: bool ret;
111:
112: thread_set_active_condvar(&this->cv);
113:
114: /* while a CriticalSection is recursive, waiting in a condvar releases
115: * only one mutex. So release (and reacquire) all locks except the last. */
116: times = mutex->times;
117: while (mutex->times-- > 1)
118: {
119: LeaveCriticalSection(&mutex->cs);
120: }
121:
122: ret = SleepConditionVariableCS(&this->cv, &mutex->cs, timeout);
123:
124: while (++mutex->times < times)
125: {
126: EnterCriticalSection(&mutex->cs);
127: }
128:
129: thread_set_active_condvar(NULL);
130:
131: return ret == 0;
132: }
133:
134: METHOD(condvar_t, wait_, void,
135: private_condvar_t *this, mutex_t *mutex)
136: {
137: timed_wait(this, mutex, INFINITE);
138: }
139:
140: METHOD(condvar_t, timed_wait_abs, bool,
141: private_condvar_t *this, mutex_t *mutex, timeval_t tv)
142: {
143: DWORD timeout;
144: timeval_t now, diff;
145:
146: time_monotonic(&now);
147: if (timercmp(&now, &tv, >))
148: {
149: return TRUE;
150: }
151: timersub(&tv, &now, &diff);
152: timeout = diff.tv_sec * 1000 + diff.tv_usec / 1000;
153:
154: return timed_wait(this, mutex, timeout);
155: }
156:
157: METHOD(condvar_t, signal_, void,
158: private_condvar_t *this)
159: {
160: WakeConditionVariable(&this->cv);
161: }
162:
163: METHOD(condvar_t, broadcast, void,
164: private_condvar_t *this)
165: {
166: WakeAllConditionVariable(&this->cv);
167: }
168:
169: METHOD(condvar_t, condvar_destroy, void,
170: private_condvar_t *this)
171: {
172: free(this);
173: }
174:
175: /*
176: * see header file
177: */
178: condvar_t *condvar_create(condvar_type_t type)
179: {
180: private_condvar_t *this;
181:
182: INIT(this,
183: .public = {
184: .wait = _wait_,
185: .timed_wait = _timed_wait,
186: .timed_wait_abs = _timed_wait_abs,
187: .signal = _signal_,
188: .broadcast = _broadcast,
189: .destroy = _condvar_destroy,
190: }
191: );
192:
193: InitializeConditionVariable(&this->cv);
194:
195: return &this->public;
196: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>