1 /* vi:ai:et:ts=8 sw=2
2  */
3 /*
4  * wzdftpd - a modular and cool ftp server
5  * Copyright (C) 2002-2004  Pierre Chifflier
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program 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 program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20  *
21  * As a special exemption, Pierre Chifflier
22  * and other respective copyright holders give permission to link this program
23  * with OpenSSL, and distribute the resulting executable, without including
24  * the source code for OpenSSL in the source distribution.
25  */
26 /** \file wzd_mutex.c
27   * \brief Mutexes implementation
28   * \warning This file contains many platform-dependant code, and supports
29   * only multithread code.
30   */
31 
32 #include "wzd_all.h"
33 
34 #ifndef WZD_USE_PCH
35 
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <errno.h>
40 #include <sys/types.h>
41 
42 #ifdef WIN32
43 # define _WIN32_WINNT    0x500
44 # include <windows.h>
45 #else
46 #include <unistd.h>
47 #include <pthread.h>
48 #endif
49 
50 struct wzd_context_t;
51 
52 #include "wzd_mutex.h"
53 
54 #include "wzd_debug.h"
55 
56 #else /* WZD_USE_PCH */
57 #ifdef WIN32
58 #define _WIN32_WINNT    0x500
59 #include <windows.h>
60 #endif
61 #endif /* WZD_USE_PCH */
62 
63 struct _wzd_mutex_t {
64 #ifndef WIN32
65   pthread_mutex_t _mutex;
66 #else
67   CRITICAL_SECTION _mutex;
68 #endif
69 };
70 
71 
72 /** create a mutex */
wzd_mutex_create(unsigned long key)73 wzd_mutex_t * wzd_mutex_create(unsigned long key)
74 {
75   int ret;
76   struct _wzd_mutex_t * m;
77 
78   /* check unicity ?! */
79 
80   /* allocate new mutex */
81   m = (struct _wzd_mutex_t*)wzd_malloc(sizeof(struct _wzd_mutex_t));
82 
83   /* initilization */
84 #ifndef WIN32
85   {
86     pthread_mutex_t pth = PTHREAD_MUTEX_INITIALIZER;
87     memcpy((void*)&m->_mutex, (const void*)&pth, sizeof(pth));
88     ret = pthread_mutex_init(&(m->_mutex), NULL);
89   }
90 #else
91   InitializeCriticalSection(&m->_mutex);
92   ret = 0;
93 #endif
94 
95   if (ret) { wzd_free(m); return NULL; }
96 
97   return m;
98 }
99 
100 
101 /** destroy mutex */
wzd_mutex_destroy(wzd_mutex_t * mutex)102 void wzd_mutex_destroy(wzd_mutex_t * mutex)
103 {
104   if (mutex) {
105 #ifndef WIN32
106     pthread_mutex_destroy(&mutex->_mutex);
107 #else
108     DeleteCriticalSection(&mutex->_mutex);
109 #endif
110     wzd_free(mutex);
111   }
112 }
113 
114 
115 
116 /* lock a mutex */
wzd_mutex_lock(wzd_mutex_t * mutex)117 int wzd_mutex_lock(wzd_mutex_t * mutex)
118 {
119   if (mutex) {
120 #ifndef WIN32
121     return pthread_mutex_lock(&mutex->_mutex);
122 #else
123     EnterCriticalSection(&mutex->_mutex);
124     return 0;
125 #endif
126   }
127   return 1;
128 }
129 
130 
131 /* try to lock a mutex */
wzd_mutex_trylock(wzd_mutex_t * mutex)132 int wzd_mutex_trylock(wzd_mutex_t * mutex)
133 {
134   if (mutex) {
135 #ifndef WIN32
136     return pthread_mutex_trylock(&mutex->_mutex);
137 #else
138     TryEnterCriticalSection(&mutex->_mutex);
139     return 0;
140 #endif
141   }
142   return 1;
143 }
144 
145 
146 /* unlock a mutex */
wzd_mutex_unlock(wzd_mutex_t * mutex)147 int wzd_mutex_unlock(wzd_mutex_t * mutex)
148 {
149   if (mutex) {
150 #ifndef WIN32
151     return pthread_mutex_unlock(&mutex->_mutex);
152 #else
153     LeaveCriticalSection(&mutex->_mutex);
154     return 0;
155 #endif
156   }
157   return 1;
158 }
159