From 63561f9937d11b1371a2de2511b903035818b42f Mon Sep 17 00:00:00 2001 From: "Sven M. Hallberg" Date: Wed, 3 Sep 2014 16:36:30 +0200 Subject: [PATCH] wrap lifetimes of CattaServer and CattaSimplePoll in WSAStartup/WSACleanup --- src/compat/windows/wincompat.c | 17 +++++++++++++++++ src/compat/windows/wincompat.h | 5 +++++ src/internal.h | 2 ++ src/server.c | 3 +++ src/simple-watch.c | 3 +++ 5 files changed, 30 insertions(+) diff --git a/src/compat/windows/wincompat.c b/src/compat/windows/wincompat.c index 4433b5b..4e3145e 100644 --- a/src/compat/windows/wincompat.c +++ b/src/compat/windows/wincompat.c @@ -4,6 +4,8 @@ #include #include +#include + // helper: convert WSAGetLastError() to an errno constant static int wsa_errno(void) { @@ -29,6 +31,21 @@ static int wsa_errno(void) } } +void winsock_init(void) +{ + WSADATA wsa; + int error; + + if((error = WSAStartup(MAKEWORD(2,2), &wsa)) != 0) + catta_log_error("WSAStartup() failed: %d", error); +} + +void winsock_exit(void) +{ + if(WSACleanup() == SOCKET_ERROR) + catta_log_warn("WSACleanup() failed: %d", WSAGetLastError()); +} + ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags) { LPFN_WSARECVMSG WSARecvMsg = NULL; diff --git a/src/compat/windows/wincompat.h b/src/compat/windows/wincompat.h index c736f75..de3396c 100644 --- a/src/compat/windows/wincompat.h +++ b/src/compat/windows/wincompat.h @@ -16,6 +16,11 @@ #include +// wrappers around WSAStartup/WSACleanup to avoid clutter +void winsock_init(void); +void winsock_exit(void); + + // Winsock doesn't have recvmsg/sendmsg but offers the same functionality // with WSARecvMsg/WSASendMsg, so we implement the former in terms of the // latter. diff --git a/src/internal.h b/src/internal.h index b74ce25..789f363 100644 --- a/src/internal.h +++ b/src/internal.h @@ -50,6 +50,8 @@ typedef struct CattaEntry CattaEntry; #ifndef _WIN32 #define closesocket close +#define winsock_init() +#define winsock_exit() #endif typedef struct CattaLegacyUnicastReflectSlot CattaLegacyUnicastReflectSlot; diff --git a/src/server.c b/src/server.c index 1dda8b4..7f84e5a 100644 --- a/src/server.c +++ b/src/server.c @@ -1381,12 +1381,14 @@ CattaServer *catta_server_new(const CattaPoll *poll_api, const CattaServerConfig else catta_server_config_init(&s->config); + winsock_init(); // on Windows, call WSAStartup; no-op on other platforms if ((e = setup_sockets(s)) < 0) { if (error) *error = e; catta_server_config_free(&s->config); catta_free(s); + winsock_exit(); return NULL; } @@ -1533,6 +1535,7 @@ void catta_server_free(CattaServer* s) { catta_server_config_free(&s->config); catta_free(s); + winsock_exit(); // on Windows, call WSACleanup(); no-op on other platforms } const char* catta_server_get_domain_name(CattaServer *s) { diff --git a/src/simple-watch.c b/src/simple-watch.c index 77da9f8..7a0052d 100644 --- a/src/simple-watch.c +++ b/src/simple-watch.c @@ -309,8 +309,10 @@ CattaSimplePoll *catta_simple_poll_new(void) { if (!(s = catta_new(CattaSimplePoll, 1))) return NULL; + winsock_init(); // on Windows, pipe uses sockets; no-op on other platforms if (pipe(s->wakeup_pipe) < 0) { catta_free(s); + winsock_exit(); return NULL; } @@ -368,6 +370,7 @@ void catta_simple_poll_free(CattaSimplePoll *s) { closesocket(s->wakeup_pipe[1]); catta_free(s); + winsock_exit(); // match the winsock_init in catta_simple_poll_new } static int rebuild(CattaSimplePoll *s) { -- 2.39.5