A simple cross-platform mutex lock

Source: Internet
Author: User

Preface
Mutex lock is used to ensure that only a single thread or process has mutex access to shared resources at any time. Here, the mutex in posix thread, the mutex in win32, and the critical section are used, they are collectively referred to as mutex locks. Their features are as follows:
● Scope: thread locks and process locks. The former is only used between multiple threads in the same process, while the latter is used between processes. Obviously, it can also be used between multiple threads in the same process, but the efficiency is low. The mutex of posix can be either a thread lock or a process lock, which is determined by one of its attributes: pthread_process_shared or pthread_process_private. The critical section in win32 is a thread lock, and the mutex can be either a thread lock or a process lock, which is determined by a name: the 3rd parameters in createmutex.
● Type: mutex in posix, including common locks, recursive locks, detection locks, and adaptive locks. The critical section in win32 can be locked and unlocked multiple times in the same thread, which is equivalent to recursive locks, the mutex is equivalent to a common lock.
● Operation: five types of operations are available, including creating locks, locking, unlocking, checking locks, and destroying locks. The locking operation can be divided into permanent waiting and timeout waiting. For the critical section in win32, there is no lock for timeout wait.

Interface
For all lock operations, 0 is returned successfully. If posix fails, an error code other than 0 is returned. win32 returns-1. Call getlasterror to obtain the error code. For timeout locks, the timeout of the 2nd parameters is not a time difference, but an absolute expiration time. For mutex in win32, 1 is discarded and 2 is returned for timeout.
1 # ifdef _ cplusplus
2 extern "C "{
3 # endif
4
5 # ifdef _ POSIX_THREAD
6 # include <pthread. h>
7 # include <sys/time. h>
8
9 typedef pthread_mutex_t mutex_t;
10 typedef pthread_mutexattr_t mutexattr_t;
11 typedef void SECURITY_ATTRIBUTES;
12
13 # elif defined (_ WIN32_THREAD)
14 # ifndef _ WIN32_WINNT
15 # define _ WIN32_WINNT 0x0501
16 # endif
17 # include <winsock2.h>
18
19 typedef struct
20 {
21 int type _;
22 union
23 {
24 HANDLE proc_lock _;
25 CRITICAL_SECTION thr_lock _;
26 };
27} mutex_t;
28 typedef void mutexattr_t;
29
30 # else
31 # error Currently only support win32 and posix thread models
32 # endif
33
34 # define MUTEX_THREAD_SHARED 1
35 # define MUTEX_PROCESS_SHARED 2
36
37 int mutex_init (mutex_t * m, int scope, int type, const char * name, mutexattr_t * attr, SECURITY_ATTRIBUTES * sa );
38
39 int mutex_lock (mutex_t * m );
40
41 int mutex_timedlock (mutex_t * m, const struct timeval * val );
42
43 int mutex_trylock (mutex_t * m );
44
45 int mutex_unlock (mutex_t * m );
46
47 int mutex_destroy (mutex_t * m );
48
49 # ifdef _ cplusplus
50}
51 # endif

Implementation
1 int mutex_init (mutex_t * m, int scope, int type, const char * name, mutexattr_t * attr, SECURITY_ATTRIBUTES * sa)
2 {
3 # ifdef _ POSIX_THREAD
4 int ret, init = 0;
5 pthread_mutexattr_t tmp;
6 if (0 = attr) attr = & tmp;
7 if (attr = & tmp)
8 {
9 ret = pthread_mutexattr_init (attr );
10 if (0 = ret) init = 1;
11}
12 if (0 = ret & 0! = Scope)
13 {
14 # ifdef _ POSIX_THREAD_PROCESS_SHARED
15 ret = pthread_mutexattr_setpshared (attr, lock_scope );
16 # endif
17}
18 if (0 = ret & 0! = Type)
19 {
20 # ifdef _ USE_UNIX98
21 ret = pthread_mutexattr_settype (attr, lock_type );
22 # endif
23}
24 if (0 = ret)
25 ret = pthread_mutex_init (m, attr );
26 if (1 = init & attr = & tmp)
27 pthread_mutexattr_destroy (attr );
28 return ret;
29 # else
30 m-> type _ = scope;
31 switch (m-> type _)
32 {
33 case MUTEX_THREAD_SHARED:
34 _ try
35 {
36 InitializeCriticalSection (& m-> thr_lock _);
37}
38 _ handler T (EXCEPTION_EXECUTE_HANDLER)
39 {
40 return-1;
41}
42 return 0;
43
44 case MUTEX_PROCESS_SHARED:
45 m-> proc_lock _ = CreateMutexA (sa, FALSE, name );
46 if (0 = m-> proc_lock _ & ERROR_ACCESS_DENIED = GetLastError ())
47 m-> proc_lock _ = OpenMutexA (MUTEX_ALL_ACCESS, FALSE, name );
48 if (0 = m-> proc_lock _)
49 return-1;
50 return 0;
51
52 default: return-1;
53}
54 # endif
55}
56
57 int mutex_lock (mutex_t * m)
58 {
59 # ifdef _ POSIX_THREAD
60 return pthread_mutex_lock (m );
61 # else
62 switch (m-> type _)
63 {
64 case MUTEX_THREAD_SHARED:
65 EnterCriticalSection (& m-> thr_lock _);
66 return 0;
67
68 case MUTEX_PROCESS_SHARED:
69 switch (WaitForSingleObject (m-> proc_lock _, INFINITE ))
70 {
71 case WAIT_OBJECT_0: return 0;
72 case WAIT_ABANDONED: return 1;
73 default: return-1;
74}
75 break;
76
77 default: return-1;
78}
79 # endif
80}
81
82 int mutex_timedlock (mutex_t * m, const struct timeval * val)
83 {
84 // val shocould be an absolute time.
85 # ifdef _ POSIX_THREAD
86 struct timespec ts = {. TV _sec = val-> TV _sec,. TV _nsec = val-> TV _usec * 1000 };
87 return pthread_mutex_timedlock (m, & ts );
88 # else
89 switch (m-> type _)
90 {
91 // not support CriticalSection, so simply return-1.
92 case MUTEX_THREAD_SHARED:
93 return-1;
94
95 case MUTEX_PROCESS_SHARED:
96 {
97 FILETIME ft;
98 struct timeval cur, diff;
99
100 GetSystemTimeAsFileTime (& ft );
101 cur = FileTime2TimeVal (& ft );
102 diff = timeval_sub (val, & cur );
103
104 switch (WaitForSingleObject (m-> proc_lock _, timeval_millsec (& diff )))
105 {
106 case WAIT_OBJECT_0: return 0;
107 case WAIT_ABANDONED: return 1;
108 case WAIT_TIMEOUT: return 2;
109 default: return-1;
110}
111}
112 break;
113
114 default: return-1;
115}
116 # endif
117}
118
119 int mutex_trylock (mutex_t * m)
120 {
121 # ifdef _ POSIX_THREAD
122 return pthread_mutex_trylock (m );
123 # else
124 switch (m-> type _)
125 {
126 case MUTEX_THREAD_SHARED:
127 if (! TryEnterCriticalSection (& m-> thr_lock _))
128 return-1;
129 return 0;
130
131 case MUTEX_PROCESS_SHARED:
132 switch (WaitForSingleObject (m-> proc_lock _, 0 ))
133 {
134 case WAIT_OBJECT_0: return 0;
135 case WAIT_ABANDONED: return 1;
136 case WAIT_TIMEOUT: return 2;
137 default: return-1;
138}
139 break;
140
141 default: return-1;
142}
143 # endif
144}
145
146 int mutex_unlock (mutex_t * m)
147 {
148 # ifdef _ POSIX_THREAD
149 return pthread_mutex_unlock (m );
150 # else
151 switch (m-> type _)
152 {
153 case MUTEX_THREAD_SHARED:
154 LeaveCriticalSection (& m-> thr_lock _);
155 return 0;
156
157 case MUTEX_PROCESS_SHARED:
158 if (! ReleaseMutex (m-> proc_lock _))
159 return-1;
160 return 0;
161
162 default: return-1;
163}
164 # endif
165}
166www.2cto.com
167 int mutex_destroy (mutex_t * m)
168 {
169 # ifdef _ POSIX_THREAD
170 return pthread_mutex_destroy (m );
171 # else
172 switch (m-> type _)
173 {
174 case MUTEX_THREAD_SHARED:
175 DeleteCriticalSection (& m-> thr_lock _);
176 return 0;
177
178 case MUTEX_PROCESS_SHARED:
179 if (! CloseHandle (m-> proc_lock _))
180 return-1;
181 return 0;
182
183 default: return-1;
184}
185 # endif
186}

 

Author: December

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.