Home | History | Annotate | Download | only in include
      1 /*
      2   This file is part of libmicrohttpd
      3   Copyright (C) 2014 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.
     17   If not, see <http://www.gnu.org/licenses/>.
     18 */
     19 
     20 /**
     21  * @file include/platform_interface.h
     22  * @brief  internal platform abstraction functions
     23  * @author Karlson2k (Evgeny Grin)
     24  */
     25 
     26 #ifndef MHD_PLATFORM_INTERFACE_H
     27 #define MHD_PLATFORM_INTERFACE_H
     28 
     29 #include "platform.h"
     30 #if defined(_WIN32) && !defined(__CYGWIN__)
     31 #include "w32functions.h"
     32 #endif
     33 
     34 /* *****************************
     35      General function mapping
     36    *****************************/
     37 #if !defined(_WIN32) || defined(__CYGWIN__)
     38 /**
     39  * Check two strings case-insensitive equality
     40  * @param a first string to check
     41  * @param b second string to check
     42  * @return boolean true if strings are equal, boolean false if strings are unequal
     43  */
     44 #define MHD_str_equal_caseless_(a,b) (0==strcasecmp((a),(b)))
     45 #else
     46 /**
     47  * Check two strings case-insensitive equality
     48  * @param a first string to check
     49  * @param b second string to check
     50  * @return boolean true if strings are equal, boolean false if strings are unequal
     51  */
     52 #define MHD_str_equal_caseless_(a,b) (0==_stricmp((a),(b)))
     53 #endif
     54 
     55 #if !defined(_WIN32) || defined(__CYGWIN__)
     56 /**
     57  * Check not more than n chars in two strings case-insensitive equality
     58  * @param a first string to check
     59  * @param b second string to check
     60  * @param n maximum number of chars to check
     61  * @return boolean true if strings are equal, boolean false if strings are unequal
     62  */
     63 #define MHD_str_equal_caseless_n_(a,b,n) (0==strncasecmp((a),(b),(n)))
     64 #else
     65 /**
     66  * Check not more than n chars in two strings case-insensitive equality
     67  * @param a first string to check
     68  * @param b second string to check
     69  * @param n maximum number of chars to check
     70  * @return boolean true if strings are equal, boolean false if strings are unequal
     71  */
     72 #define MHD_str_equal_caseless_n_(a,b,n) (0==_strnicmp((a),(b),(n)))
     73 #endif
     74 
     75 /* Platform-independent snprintf name */
     76 #if !defined(_WIN32) || defined(__CYGWIN__)
     77 #define MHD_snprintf_ snprintf
     78 #else
     79 #define MHD_snprintf_ W32_snprintf
     80 #endif
     81 
     82 
     83 
     84 /* MHD_socket_close_(fd) close any FDs (non-W32) / close only socket FDs (W32) */
     85 #if !defined(_WIN32) || defined(__CYGWIN__)
     86 #define MHD_socket_close_(fd) close((fd))
     87 #else
     88 #define MHD_socket_close_(fd) closesocket((fd))
     89 #endif
     90 
     91 /* MHD_socket_errno_ is errno of last function (non-W32) / errno of last socket function (W32) */
     92 #if !defined(_WIN32) || defined(__CYGWIN__)
     93 #define MHD_socket_errno_ errno
     94 #else
     95 #define MHD_socket_errno_ MHD_W32_errno_from_winsock_()
     96 #endif
     97 
     98 /* MHD_socket_last_strerr_ is description string of last errno (non-W32) /
     99  *                            description string of last socket error (W32) */
    100 #if !defined(_WIN32) || defined(__CYGWIN__)
    101 #define MHD_socket_last_strerr_() strerror(errno)
    102 #else
    103 #define MHD_socket_last_strerr_() MHD_W32_strerror_last_winsock_()
    104 #endif
    105 
    106 /* MHD_strerror_ is strerror (both non-W32/W32) */
    107 #if !defined(_WIN32) || defined(__CYGWIN__)
    108 #define MHD_strerror_(errnum) strerror((errnum))
    109 #else
    110 #define MHD_strerror_(errnum) MHD_W32_strerror_((errnum))
    111 #endif
    112 
    113 /* MHD_set_socket_errno_ set errno to errnum (non-W32) / set socket last error to errnum (W32) */
    114 #if !defined(_WIN32) || defined(__CYGWIN__)
    115 #define MHD_set_socket_errno_(errnum) errno=(errnum)
    116 #else
    117 #define MHD_set_socket_errno_(errnum) MHD_W32_set_last_winsock_error_((errnum))
    118 #endif
    119 
    120 /* MHD_SYS_select_ is wrapper macro for system select() function */
    121 #if !defined(MHD_WINSOCK_SOCKETS)
    122 #define MHD_SYS_select_(n,r,w,e,t) select((n),(r),(w),(e),(t))
    123 #else
    124 #define MHD_SYS_select_(n,r,w,e,t) select((int)0,(r),(w),(e),(t))
    125 #endif
    126 
    127 #if defined(HAVE_POLL)
    128 /* MHD_sys_poll_ is wrapper macro for system poll() function */
    129 #if !defined(MHD_WINSOCK_SOCKETS)
    130 #define MHD_sys_poll_ poll
    131 #else  /* MHD_WINSOCK_SOCKETS */
    132 #define MHD_sys_poll_ WSAPoll
    133 #endif /* MHD_WINSOCK_SOCKETS */
    134 #endif /* HAVE_POLL */
    135 
    136 /* MHD_pipe_ create pipe (!MHD_DONT_USE_PIPES) /
    137  *           create two connected sockets (MHD_DONT_USE_PIPES) */
    138 #ifndef MHD_DONT_USE_PIPES
    139 #define MHD_pipe_(fdarr) pipe((fdarr))
    140 #else /* MHD_DONT_USE_PIPES */
    141 #if !defined(_WIN32) || defined(__CYGWIN__)
    142 #define MHD_pipe_(fdarr) socketpair(AF_LOCAL, SOCK_STREAM, 0, (fdarr))
    143 #else /* !defined(_WIN32) || defined(__CYGWIN__) */
    144 #define MHD_pipe_(fdarr) MHD_W32_pair_of_sockets_((fdarr))
    145 #endif /* !defined(_WIN32) || defined(__CYGWIN__) */
    146 #endif /* MHD_DONT_USE_PIPES */
    147 
    148 /* MHD_pipe_errno_ is errno of last function (!MHD_DONT_USE_PIPES) /
    149  *                    errno of last emulated pipe function (MHD_DONT_USE_PIPES) */
    150 #ifndef MHD_DONT_USE_PIPES
    151 #define MHD_pipe_errno_ errno
    152 #else
    153 #define MHD_pipe_errno_ MHD_socket_errno_
    154 #endif
    155 
    156 /* MHD_pipe_last_strerror_ is description string of last errno (!MHD_DONT_USE_PIPES) /
    157  *                            description string of last pipe error (MHD_DONT_USE_PIPES) */
    158 #ifndef MHD_DONT_USE_PIPES
    159 #define MHD_pipe_last_strerror_() strerror(errno)
    160 #else
    161 #define MHD_pipe_last_strerror_() MHD_socket_last_strerr_()
    162 #endif
    163 
    164 /* MHD_pipe_write_ write data to real pipe (!MHD_DONT_USE_PIPES) /
    165  *                 write data to emulated pipe (MHD_DONT_USE_PIPES) */
    166 #ifndef MHD_DONT_USE_PIPES
    167 #define MHD_pipe_write_(fd, ptr, sz) write((fd), (const void*)(ptr), (sz))
    168 #else
    169 #define MHD_pipe_write_(fd, ptr, sz) send((fd), (const char*)(ptr), (sz), 0)
    170 #endif
    171 
    172 /* MHD_pipe_read_ read data from real pipe (!MHD_DONT_USE_PIPES) /
    173  *                read data from emulated pipe (MHD_DONT_USE_PIPES) */
    174 #ifndef MHD_DONT_USE_PIPES
    175 #define MHD_pipe_read_(fd, ptr, sz) read((fd), (void*)(ptr), (sz))
    176 #else
    177 #define MHD_pipe_read_(fd, ptr, sz) recv((fd), (char*)(ptr), (sz), 0)
    178 #endif
    179 
    180 /* MHD_pipe_close_(fd) close any FDs (non-W32) /
    181  *                     close emulated pipe FDs (W32) */
    182 #ifndef MHD_DONT_USE_PIPES
    183 #define MHD_pipe_close_(fd) close((fd))
    184 #else
    185 #define MHD_pipe_close_(fd) MHD_socket_close_((fd))
    186 #endif
    187 
    188 /* MHD_INVALID_PIPE_ is a value of bad pipe FD */
    189 #ifndef MHD_DONT_USE_PIPES
    190 #define MHD_INVALID_PIPE_ (-1)
    191 #else
    192 #define MHD_INVALID_PIPE_ MHD_INVALID_SOCKET
    193 #endif
    194 
    195 #if !defined(_WIN32) || defined(__CYGWIN__)
    196 #define MHD_random_() random()
    197 #else
    198 #define MHD_random_() MHD_W32_random_()
    199 #endif
    200 
    201 #if defined(MHD_USE_POSIX_THREADS)
    202 typedef pthread_t MHD_thread_handle_;
    203 #elif defined(MHD_USE_W32_THREADS)
    204 #include <windows.h>
    205 typedef HANDLE MHD_thread_handle_;
    206 #else
    207 #error "No threading API is available."
    208 #endif
    209 
    210 #if defined(MHD_USE_POSIX_THREADS)
    211 #define MHD_THRD_RTRN_TYPE_ void*
    212 #define MHD_THRD_CALL_SPEC_
    213 #elif defined(MHD_USE_W32_THREADS)
    214 #define MHD_THRD_RTRN_TYPE_ unsigned
    215 #define MHD_THRD_CALL_SPEC_ __stdcall
    216 #endif
    217 
    218 #if defined(MHD_USE_POSIX_THREADS)
    219 /**
    220  * Wait until specified thread is ended
    221  * @param thread ID to watch
    222  * @return zero on success, nonzero on failure
    223  */
    224 #define MHD_join_thread_(thread) pthread_join((thread), NULL)
    225 #elif defined(MHD_USE_W32_THREADS)
    226 /**
    227  * Wait until specified thread is ended
    228  * Close thread handle on success
    229  * @param thread handle to watch
    230  * @return zero on success, nonzero on failure
    231  */
    232 #define MHD_join_thread_(thread) (WAIT_OBJECT_0 == WaitForSingleObject((thread), INFINITE) ? (CloseHandle((thread)), 0) : 1 )
    233 #endif
    234 
    235 #if defined(MHD_USE_W32_THREADS)
    236 #define MHD_W32_MUTEX_ 1
    237 #include <windows.h>
    238 typedef CRITICAL_SECTION MHD_mutex_;
    239 #elif defined(HAVE_PTHREAD_H) && defined(MHD_USE_POSIX_THREADS)
    240 #define MHD_PTHREAD_MUTEX_ 1
    241 typedef pthread_mutex_t MHD_mutex_;
    242 #else
    243 #error "No base mutex API is available."
    244 #endif
    245 
    246 #if defined(MHD_PTHREAD_MUTEX_)
    247 /**
    248  * Create new mutex.
    249  * @param mutex pointer to the mutex
    250  * @return #MHD_YES on success, #MHD_NO on failure
    251  */
    252 #define MHD_mutex_create_(mutex) \
    253   ((0 == pthread_mutex_init ((mutex), NULL)) ? MHD_YES : MHD_NO)
    254 #elif defined(MHD_W32_MUTEX_)
    255 /**
    256  * Create new mutex.
    257  * @param mutex pointer to mutex
    258  * @return #MHD_YES on success, #MHD_NO on failure
    259  */
    260 #define MHD_mutex_create_(mutex) \
    261   ((NULL != (mutex) && 0 != InitializeCriticalSectionAndSpinCount((mutex),2000)) ? MHD_YES : MHD_NO)
    262 #endif
    263 
    264 #if defined(MHD_PTHREAD_MUTEX_)
    265 /**
    266  * Destroy previously created mutex.
    267  * @param mutex pointer to mutex
    268  * @return #MHD_YES on success, #MHD_NO on failure
    269  */
    270 #define MHD_mutex_destroy_(mutex) \
    271   ((0 == pthread_mutex_destroy ((mutex))) ? MHD_YES : MHD_NO)
    272 #elif defined(MHD_W32_MUTEX_)
    273 /**
    274  * Destroy previously created mutex.
    275  * @param mutex pointer to mutex
    276  * @return #MHD_YES on success, #MHD_NO on failure
    277  */
    278 #define MHD_mutex_destroy_(mutex) \
    279   ((NULL != (mutex)) ? (DeleteCriticalSection(mutex), MHD_YES) : MHD_NO)
    280 #endif
    281 
    282 #if defined(MHD_PTHREAD_MUTEX_)
    283 /**
    284  * Acquire lock on previously created mutex.
    285  * If mutex was already locked by other thread, function
    286  * blocks until mutex becomes available.
    287  * @param mutex pointer to mutex
    288  * @return #MHD_YES on success, #MHD_NO on failure
    289  */
    290 #define MHD_mutex_lock_(mutex) \
    291   ((0 == pthread_mutex_lock((mutex))) ? MHD_YES : MHD_NO)
    292 #elif defined(MHD_W32_MUTEX_)
    293 /**
    294  * Acquire lock on previously created mutex.
    295  * If mutex was already locked by other thread, function
    296  * blocks until mutex becomes available.
    297  * @param mutex pointer to mutex
    298  * @return #MHD_YES on success, #MHD_NO on failure
    299  */
    300 #define MHD_mutex_lock_(mutex) \
    301   ((NULL != (mutex)) ? (EnterCriticalSection((mutex)), MHD_YES) : MHD_NO)
    302 #endif
    303 
    304 #if defined(MHD_PTHREAD_MUTEX_)
    305 /**
    306  * Try to acquire lock on previously created mutex.
    307  * Function returns immediately.
    308  * @param mutex pointer to mutex
    309  * @return #MHD_YES if mutex is locked, #MHD_NO if
    310  * mutex was not locked.
    311  */
    312 #define MHD_mutex_trylock_(mutex) \
    313   ((0 == pthread_mutex_trylock((mutex))) ? MHD_YES : MHD_NO)
    314 #elif defined(MHD_W32_MUTEX_)
    315 /**
    316  * Try to acquire lock on previously created mutex.
    317  * Function returns immediately.
    318  * @param mutex pointer to mutex
    319  * @return #MHD_YES if mutex is locked, #MHD_NO if
    320  * mutex was not locked.
    321  */
    322 #define MHD_mutex_trylock_(mutex) \
    323   ((NULL != (mutex) && 0 != TryEnterCriticalSection ((mutex))) ? MHD_YES : MHD_NO)
    324 #endif
    325 
    326 #if defined(MHD_PTHREAD_MUTEX_)
    327 /**
    328  * Unlock previously created and locked mutex.
    329  * @param mutex pointer to mutex
    330  * @return #MHD_YES on success, #MHD_NO on failure
    331  */
    332 #define MHD_mutex_unlock_(mutex) \
    333   ((0 == pthread_mutex_unlock((mutex))) ? MHD_YES : MHD_NO)
    334 #elif defined(MHD_W32_MUTEX_)
    335 /**
    336  * Unlock previously created and locked mutex.
    337  * @param mutex pointer to mutex
    338  * @return #MHD_YES on success, #MHD_NO on failure
    339  */
    340 #define MHD_mutex_unlock_(mutex) \
    341   ((NULL != (mutex)) ? (LeaveCriticalSection((mutex)), MHD_YES) : MHD_NO)
    342 #endif
    343 
    344 #endif // MHD_PLATFORM_INTERFACE_H
    345