apple: Introduce a central compatibility header with all __APPLE__ quirks

This commit is contained in:
Martin Willi
2014-11-21 12:02:08 +01:00
parent 6e1d3f3615
commit f65779dd0f
6 changed files with 113 additions and 87 deletions
+2 -81
View File
@@ -21,41 +21,10 @@
#ifndef THREADING_THREAD_H_
#define THREADING_THREAD_H_
#include <utils/utils.h>
typedef struct thread_t thread_t;
#ifdef __APPLE__
/* thread_create is a syscall used to create Mach kernel threads and although
* there are no errors or warnings during compilation or linkage the dynamic
* linker does not use our implementation, therefore we rename it here
*/
#define thread_create(main, arg) strongswan_thread_create(main, arg)
/* on Mac OS X 10.5 several system calls we use are no cancellation points.
* fortunately, select isn't one of them, so we wrap some of the others with
* calls to select(2).
*/
#include <sys/socket.h>
#include <sys/select.h>
#define WRAP_WITH_SELECT(func, socket, ...)\
fd_set rfds; FD_ZERO(&rfds); FD_SET(socket, &rfds);\
if (select(socket + 1, &rfds, NULL, NULL, NULL) <= 0) { return -1; }\
return func(socket, __VA_ARGS__)
static inline int cancellable_accept(int socket, struct sockaddr *address,
socklen_t *address_len)
{
WRAP_WITH_SELECT(accept, socket, address, address_len);
}
#define accept cancellable_accept
static inline int cancellable_recvfrom(int socket, void *buffer, size_t length,
int flags, struct sockaddr *address, socklen_t *address_len)
{
WRAP_WITH_SELECT(recvfrom, socket, buffer, length, flags, address, address_len);
}
#define recvfrom cancellable_recvfrom
#endif /* __APPLE__ */
/**
* Main function of a thread.
*
@@ -189,52 +158,4 @@ void threads_init();
*/
void threads_deinit();
#ifdef __APPLE__
/*
* While select() is a cancellation point, it seems that OS X does not honor
* pending cancellation points when entering the function. We manually test for
* and honor pending cancellation requests, but this obviously can't prevent
* some race conditions where the the cancellation happens after the check,
* but before the select.
*/
static inline int precancellable_select(int nfds, fd_set *restrict readfds,
fd_set *restrict writefds, fd_set *restrict errorfds,
struct timeval *restrict timeout)
{
if (thread_cancelability(TRUE))
{
thread_cancellation_point();
}
else
{
thread_cancelability(FALSE);
}
return select(nfds, readfds, writefds, errorfds, timeout);
}
#define select precancellable_select
#include <poll.h>
/*
* The same as to select(2) applies to poll(2)
*/
static inline int precancellable_poll(struct pollfd fds[], nfds_t nfds,
int timeout)
{
if (thread_cancelability(TRUE))
{
thread_cancellation_point();
}
else
{
thread_cancelability(FALSE);
}
return poll(fds, nfds, timeout);
}
#define poll precancellable_poll
#endif /* __APPLE__ */
#endif /** THREADING_THREAD_H_ @} */