1 /*
2  * mutex.c - thread mutex implementations
3  *
4  * Copyright (C) 2011-2013 Thien-Thi Nguyen
5  * Copyright (C) 2003 Stefan Jahn <stefan@lkcc.org>
6  *
7  * This is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  *
12  * This software is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this package.  If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #include "config.h"
22 
23 #if ENABLE_LOG_MUTEX
24 
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <errno.h>
29 #ifdef HAVE_PTHREAD_H
30 # include <pthread.h>
31 #endif
32 
33 #include "woe-wait.h"
34 #include "libserveez/util.h"
35 #include "libserveez/mutex.h"
36 
37 /* Creates and initializes the given @var{mutex} object.  The mutex is
38    in an unlocked state.  The function must be called before using
39    @code{svz_mutex_lock} or @code{svz_mutex_unlock}.  The user
40    must call @code{svz_mutex_destroy} for each mutex created by this
41    function.  */
42 int
svz_mutex_create(svz_mutex_t * mutex)43 svz_mutex_create (svz_mutex_t *mutex)
44 {
45 #ifdef __MINGW32__ /* Windoze native */
46   if ((*mutex = CreateMutex (NULL, FALSE, NULL)) == NULL)
47     {
48       svz_log_sys_error ("CreateMutex");
49       return -1;
50     }
51   return 0;
52 #else /* POSIX threads */
53   return pthread_mutex_init (mutex, NULL);
54 #endif
55 }
56 
57 /* Destroys the given @var{mutex} object which has been created by
58    @code{svz_mutex_create}.  */
59 int
svz_mutex_destroy(svz_mutex_t * mutex)60 svz_mutex_destroy (svz_mutex_t *mutex)
61 {
62 #ifdef __MINGW32__
63   if (!CloseHandle (*mutex))
64     {
65       svz_log_sys_error ("CloseHandle");
66       return -1;
67     }
68   *mutex = SVZ_MUTEX_INITIALIZER;
69   return 0;
70 #else
71   if (pthread_mutex_destroy (mutex) != 0)
72     {
73       svz_log_sys_error ("pthread_mutex_destroy");
74       return -1;
75     }
76   return 0;
77 #endif
78 }
79 
80 /* Locks a @var{mutex} object and sets the current thread into an idle
81    state if the @var{mutex} object has been currently locked by another
82    thread.  */
83 int
svz_mutex_lock(svz_mutex_t * mutex)84 svz_mutex_lock (svz_mutex_t *mutex)
85 {
86 #ifdef __MINGW32__
87   if (WOE_WAIT_INF (*mutex) == WAIT_FAILED)
88     {
89       WOE_WAIT_LOG_ERROR_ANONYMOUSLY ();
90       return -1;
91     }
92   return 0;
93 #else
94   if (pthread_mutex_lock (mutex) != 0)
95     {
96       svz_log_sys_error ("pthread_mutex_lock");
97       return -1;
98     }
99   return 0;
100 #endif
101 }
102 
103 /* Releases the given @var{mutex} object and thereby possibly resumes
104    a waiting thread calling @code{svz_mutex_lock}.  */
105 int
svz_mutex_unlock(svz_mutex_t * mutex)106 svz_mutex_unlock (svz_mutex_t *mutex)
107 {
108 #ifdef __MINGW32__
109   if (!ReleaseMutex (mutex))
110     {
111       svz_log_sys_error ("ReleaseMutex");
112       return -1;
113     }
114   return 0;
115 #else
116   if (pthread_mutex_unlock (mutex) != 0)
117     {
118       svz_log_sys_error ("pthread_mutex_unlock");
119       return -1;
120     }
121   return 0;
122 #endif
123 }
124 
125 #endif  /* ENABLE_LOG_MUTEX */
126