1 /* 2 This file is part of libmicrohttpd 3 Copyright (C) 2016 Karlson2k (Evgeny Grin) 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with this library; if not, write to the Free Software 17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 19 */ 20 21 /** 22 * @file microhttpd/mhd_locks.h 23 * @brief Header for platform-independent locks abstraction 24 * @author Karlson2k (Evgeny Grin) 25 * @author Christian Grothoff 26 * 27 * Provides basic abstraction for locks/mutex. 28 * Any functions can be implemented as macro on some platforms 29 * unless explicitly marked otherwise. 30 * Any function argument can be skipped in macro, so avoid 31 * variable modification in function parameters. 32 * 33 * @warning Unlike pthread functions, most of functions return 34 * nonzero on success. 35 */ 36 37 #ifndef MHD_LOCKS_H 38 #define MHD_LOCKS_H 1 39 40 #include "mhd_options.h" 41 42 #if defined(MHD_USE_W32_THREADS) 43 # define MHD_W32_MUTEX_ 1 44 # ifndef WIN32_LEAN_AND_MEAN 45 # define WIN32_LEAN_AND_MEAN 1 46 # endif /* !WIN32_LEAN_AND_MEAN */ 47 # include <windows.h> 48 #elif defined(HAVE_PTHREAD_H) && defined(MHD_USE_POSIX_THREADS) 49 # define MHD_PTHREAD_MUTEX_ 1 50 # undef HAVE_CONFIG_H 51 # include <pthread.h> 52 # define HAVE_CONFIG_H 1 53 #else 54 # error No base mutex API is available. 55 #endif 56 57 #ifndef MHD_PANIC 58 # include <stdio.h> 59 # include <stdlib.h> 60 /* Simple implementation of MHD_PANIC, to be used outside lib */ 61 # define MHD_PANIC(msg) do { fprintf (stderr, \ 62 "Abnormal termination at %d line in file %s: %s\n", \ 63 (int) __LINE__, __FILE__, msg); abort (); \ 64 } while (0) 65 #endif /* ! MHD_PANIC */ 66 67 #if defined(MHD_PTHREAD_MUTEX_) 68 typedef pthread_mutex_t MHD_mutex_; 69 #elif defined(MHD_W32_MUTEX_) 70 typedef CRITICAL_SECTION MHD_mutex_; 71 #endif 72 73 #if defined(MHD_PTHREAD_MUTEX_) 74 /** 75 * Initialise new mutex. 76 * @param pmutex pointer to the mutex 77 * @return nonzero on success, zero otherwise 78 */ 79 #define MHD_mutex_init_(pmutex) (! (pthread_mutex_init ((pmutex), NULL))) 80 #elif defined(MHD_W32_MUTEX_) 81 /** 82 * Initialise new mutex. 83 * @param pmutex pointer to mutex 84 * @return nonzero on success, zero otherwise 85 */ 86 #define MHD_mutex_init_(pmutex) (InitializeCriticalSectionAndSpinCount ( \ 87 (pmutex),16)) 88 #endif 89 90 #if defined(MHD_PTHREAD_MUTEX_) 91 # if defined(PTHREAD_MUTEX_INITIALIZER) 92 /** 93 * Define static mutex and statically initialise it. 94 */ 95 # define MHD_MUTEX_STATIC_DEFN_INIT_(m) static MHD_mutex_ m = \ 96 PTHREAD_MUTEX_INITIALIZER 97 # endif /* PTHREAD_MUTEX_INITIALIZER */ 98 #endif 99 100 #if defined(MHD_PTHREAD_MUTEX_) 101 /** 102 * Destroy previously initialised mutex. 103 * @param pmutex pointer to mutex 104 * @return nonzero on success, zero otherwise 105 */ 106 #define MHD_mutex_destroy_(pmutex) (! (pthread_mutex_destroy ((pmutex)))) 107 #elif defined(MHD_W32_MUTEX_) 108 /** 109 * Destroy previously initialised mutex. 110 * @param pmutex pointer to mutex 111 * @return Always nonzero 112 */ 113 #define MHD_mutex_destroy_(pmutex) (DeleteCriticalSection ((pmutex)), ! 0) 114 #endif 115 116 /** 117 * Destroy previously initialised mutex and abort execution 118 * if error is detected. 119 * @param pmutex pointer to mutex 120 */ 121 #define MHD_mutex_destroy_chk_(pmutex) do { \ 122 if (! MHD_mutex_destroy_ (pmutex)) \ 123 MHD_PANIC (_ ("Failed to destroy mutex.\n")); \ 124 } while (0) 125 126 127 #if defined(MHD_PTHREAD_MUTEX_) 128 /** 129 * Acquire lock on previously initialised mutex. 130 * If mutex was already locked by other thread, function 131 * blocks until mutex becomes available. 132 * @param pmutex pointer to mutex 133 * @return nonzero on success, zero otherwise 134 */ 135 #define MHD_mutex_lock_(pmutex) (! (pthread_mutex_lock ((pmutex)))) 136 #elif defined(MHD_W32_MUTEX_) 137 /** 138 * Acquire lock on previously initialised mutex. 139 * If mutex was already locked by other thread, function 140 * blocks until mutex becomes available. 141 * @param pmutex pointer to mutex 142 * @return Always nonzero 143 */ 144 #define MHD_mutex_lock_(pmutex) (EnterCriticalSection ((pmutex)), ! 0) 145 #endif 146 147 /** 148 * Acquire lock on previously initialised mutex. 149 * If mutex was already locked by other thread, function 150 * blocks until mutex becomes available. 151 * If error is detected, execution will be aborted. 152 * @param pmutex pointer to mutex 153 */ 154 #define MHD_mutex_lock_chk_(pmutex) do { \ 155 if (! MHD_mutex_lock_ (pmutex)) \ 156 MHD_PANIC (_ ("Failed to lock mutex.\n")); \ 157 } while (0) 158 159 #if defined(MHD_PTHREAD_MUTEX_) 160 /** 161 * Unlock previously initialised and locked mutex. 162 * @param pmutex pointer to mutex 163 * @return nonzero on success, zero otherwise 164 */ 165 #define MHD_mutex_unlock_(pmutex) (! (pthread_mutex_unlock ((pmutex)))) 166 #elif defined(MHD_W32_MUTEX_) 167 /** 168 * Unlock previously initialised and locked mutex. 169 * @param pmutex pointer to mutex 170 * @return Always nonzero 171 */ 172 #define MHD_mutex_unlock_(pmutex) (LeaveCriticalSection ((pmutex)), ! 0) 173 #endif 174 175 /** 176 * Unlock previously initialised and locked mutex. 177 * If error is detected, execution will be aborted. 178 * @param pmutex pointer to mutex 179 */ 180 #define MHD_mutex_unlock_chk_(pmutex) do { \ 181 if (! MHD_mutex_unlock_ (pmutex)) \ 182 MHD_PANIC (_ ("Failed to unlock mutex.\n")); \ 183 } while (0) 184 185 186 #endif /* ! MHD_LOCKS_H */ 187