Compare commits
2 Commits
master
...
macos_clos
Author | SHA1 | Date | |
---|---|---|---|
|
1ddf289d82 | ||
|
bf7c7d8038 |
@ -9,8 +9,6 @@
|
||||
#ifdef _WIN32
|
||||
# include <ws2tcpip.h>
|
||||
typedef int socklen_t;
|
||||
typedef SOCKET sc_raw_socket;
|
||||
# define SC_RAW_SOCKET_NONE INVALID_SOCKET
|
||||
#else
|
||||
# include <sys/types.h>
|
||||
# include <sys/socket.h>
|
||||
@ -23,8 +21,6 @@
|
||||
typedef struct sockaddr_in SOCKADDR_IN;
|
||||
typedef struct sockaddr SOCKADDR;
|
||||
typedef struct in_addr IN_ADDR;
|
||||
typedef int sc_raw_socket;
|
||||
# define SC_RAW_SOCKET_NONE -1
|
||||
#endif
|
||||
|
||||
bool
|
||||
@ -47,17 +43,26 @@ net_cleanup(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline bool
|
||||
sc_raw_socket_close(sc_raw_socket raw_sock) {
|
||||
#ifndef _WIN32
|
||||
return !close(raw_sock);
|
||||
#else
|
||||
return !closesocket(raw_sock);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline sc_socket
|
||||
wrap(sc_raw_socket sock) {
|
||||
#ifdef _WIN32
|
||||
if (sock == INVALID_SOCKET) {
|
||||
#ifdef SC_SOCKET_CLOSE_ON_INTERRUPT
|
||||
if (sock == SC_RAW_SOCKET_NONE) {
|
||||
return SC_SOCKET_NONE;
|
||||
}
|
||||
|
||||
struct sc_socket_windows *socket = malloc(sizeof(*socket));
|
||||
struct sc_socket_wrapper *socket = malloc(sizeof(*socket));
|
||||
if (!socket) {
|
||||
LOG_OOM();
|
||||
closesocket(sock);
|
||||
sc_raw_socket_close(sock);
|
||||
return SC_SOCKET_NONE;
|
||||
}
|
||||
|
||||
@ -72,9 +77,9 @@ wrap(sc_raw_socket sock) {
|
||||
|
||||
static inline sc_raw_socket
|
||||
unwrap(sc_socket socket) {
|
||||
#ifdef _WIN32
|
||||
#ifdef SC_SOCKET_CLOSE_ON_INTERRUPT
|
||||
if (socket == SC_SOCKET_NONE) {
|
||||
return INVALID_SOCKET;
|
||||
return SC_RAW_SOCKET_NONE;
|
||||
}
|
||||
|
||||
return socket->socket;
|
||||
@ -83,17 +88,6 @@ unwrap(sc_socket socket) {
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef HAVE_SOCK_CLOEXEC // avoid unused-function warning
|
||||
static inline bool
|
||||
sc_raw_socket_close(sc_raw_socket raw_sock) {
|
||||
#ifndef _WIN32
|
||||
return !close(raw_sock);
|
||||
#else
|
||||
return !closesocket(raw_sock);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SOCK_CLOEXEC
|
||||
// If SOCK_CLOEXEC does not exist, the flag must be set manually once the
|
||||
// socket is created
|
||||
@ -248,9 +242,9 @@ net_interrupt(sc_socket socket) {
|
||||
|
||||
sc_raw_socket raw_sock = unwrap(socket);
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef SC_SOCKET_CLOSE_ON_INTERRUPT
|
||||
if (!atomic_flag_test_and_set(&socket->closed)) {
|
||||
return !closesocket(raw_sock);
|
||||
return sc_raw_socket_close(raw_sock);
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
@ -262,15 +256,15 @@ bool
|
||||
net_close(sc_socket socket) {
|
||||
sc_raw_socket raw_sock = unwrap(socket);
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef SC_SOCKET_CLOSE_ON_INTERRUPT
|
||||
bool ret = true;
|
||||
if (!atomic_flag_test_and_set(&socket->closed)) {
|
||||
ret = !closesocket(raw_sock);
|
||||
ret = sc_raw_socket_close(raw_sock);
|
||||
}
|
||||
free(socket);
|
||||
return ret;
|
||||
#else
|
||||
return !close(raw_sock);
|
||||
return sc_raw_socket_close(raw_sock);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -7,21 +7,37 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
# include <winsock2.h>
|
||||
# include <stdatomic.h>
|
||||
# define SC_SOCKET_NONE NULL
|
||||
typedef struct sc_socket_windows {
|
||||
SOCKET socket;
|
||||
atomic_flag closed;
|
||||
} *sc_socket;
|
||||
|
||||
typedef SOCKET sc_raw_socket;
|
||||
# define SC_RAW_SOCKET_NONE INVALID_SOCKET
|
||||
#else // not _WIN32
|
||||
|
||||
# include <sys/socket.h>
|
||||
# define SC_SOCKET_NONE -1
|
||||
typedef int sc_socket;
|
||||
typedef int sc_raw_socket;
|
||||
# define SC_RAW_SOCKET_NONE -1
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(__APPLE__)
|
||||
// On Windows and macOS, shutdown() does not interrupt accept() or read()
|
||||
// calls, so net_interrupt() must call close() instead, and net_close() must
|
||||
// behave accordingly.
|
||||
// This causes a small race condition (once the socket is closed, its
|
||||
// handle becomes invalid and may in theory be reassigned before another
|
||||
// thread calls accept() or read()), but it is deemed acceptable as a
|
||||
// workaround.
|
||||
# define SC_SOCKET_CLOSE_ON_INTERRUPT
|
||||
#endif
|
||||
|
||||
#ifdef SC_SOCKET_CLOSE_ON_INTERRUPT
|
||||
# include <stdatomic.h>
|
||||
# define SC_SOCKET_NONE NULL
|
||||
typedef struct sc_socket_wrapper {
|
||||
sc_raw_socket socket;
|
||||
atomic_flag closed;
|
||||
} *sc_socket;
|
||||
#else
|
||||
# define SC_SOCKET_NONE -1
|
||||
typedef sc_raw_socket sc_socket;
|
||||
#endif
|
||||
|
||||
#define IPV4_LOCALHOST 0x7F000001
|
||||
|
Loading…
x
Reference in New Issue
Block a user