From b3d911abea3b1dc96513535ec09d1176a6abd7ec Mon Sep 17 00:00:00 2001 From: Daniel Collins Date: Thu, 8 Sep 2011 00:20:34 +0000 Subject: [PATCH] Partial cleanup of locking code. --- src/ipxwrapper.c | 68 +++++++++++++++++++++++++++++++++--------------- src/ipxwrapper.h | 13 +++------ src/winsock.c | 35 ++++++++++++++++--------- 3 files changed, 73 insertions(+), 43 deletions(-) diff --git a/src/ipxwrapper.c b/src/ipxwrapper.c index db7e9c8..77dd93d 100644 --- a/src/ipxwrapper.c +++ b/src/ipxwrapper.c @@ -47,13 +47,29 @@ HMODULE winsock2_dll = NULL; HMODULE mswsock_dll = NULL; HMODULE wsock32_dll = NULL; -static HANDLE mutex = NULL; static HANDLE router_thread = NULL; struct router_vars *router = NULL; +static CRITICAL_SECTION sockets_cs; +static CRITICAL_SECTION hosts_cs; + static BOOL start_router(void); +#define INIT_CS(cs) if(!init_cs(cs, &initialised_cs)) { return FALSE; } + +static BOOL init_cs(CRITICAL_SECTION *cs, int *counter) { + if(!InitializeCriticalSectionAndSpinCount(&(router->crit_sec), 0x80000000)) { + log_printf("Failed to initialise critical section: %s", w32_error(GetLastError())); + return FALSE; + } + + (*counter)++; + return TRUE; +} + BOOL WINAPI DllMain(HINSTANCE me, DWORD why, LPVOID res) { + static int initialised_cs = 0; + if(why == DLL_PROCESS_ATTACH) { log_open(); @@ -76,11 +92,8 @@ BOOL WINAPI DllMain(HINSTANCE me, DWORD why, LPVOID res) { nics = get_interfaces(-1); - mutex = CreateMutex(NULL, FALSE, NULL); - if(!mutex) { - log_printf("Failed to create mutex"); - return FALSE; - } + INIT_CS(&sockets_cs); + INIT_CS(&hosts_cs); WSADATA wsdata; int err = WSAStartup(MAKEWORD(1,1), &wsdata); @@ -108,14 +121,17 @@ BOOL WINAPI DllMain(HINSTANCE me, DWORD why, LPVOID res) { router = NULL; } - if(mutex) { - CloseHandle(mutex); - mutex = NULL; + WSACleanup(); + + switch(initialised_cs) { + case 2: DeleteCriticalSection(&hosts_cs); + case 1: DeleteCriticalSection(&sockets_cs); + default: break; } - free_interfaces(nics); + initialised_cs = 0; - WSACleanup(); + free_interfaces(nics); reg_close(); @@ -153,7 +169,7 @@ void __stdcall *find_sym(char const *symbol) { * TODO: Change this behaviour. It is almost as bad as the BKL. */ ipx_socket *get_socket(SOCKET fd) { - lock_mutex(); + lock_sockets(); ipx_socket *ptr = sockets; @@ -166,20 +182,20 @@ ipx_socket *get_socket(SOCKET fd) { } if(!ptr) { - unlock_mutex(); + unlock_sockets(); } return ptr; } /* Lock the mutex */ -void lock_mutex(void) { - WaitForSingleObject(mutex, INFINITE); +void lock_sockets(void) { + EnterCriticalSection(&sockets_cs); } /* Unlock the mutex */ -void unlock_mutex(void) { - while(ReleaseMutex(mutex)) {} +void unlock_sockets(void) { + LeaveCriticalSection(&sockets_cs); } /* Initialize and start the router thread */ @@ -205,6 +221,8 @@ static BOOL start_router(void) { /* Add a host to the hosts list or update an existing one */ void add_host(const unsigned char *net, const unsigned char *node, uint32_t ipaddr) { + EnterCriticalSection(&hosts_cs); + ipx_host *hptr = hosts; while(hptr) { @@ -212,6 +230,7 @@ void add_host(const unsigned char *net, const unsigned char *node, uint32_t ipad hptr->ipaddr = ipaddr; hptr->last_packet = time(NULL); + LeaveCriticalSection(&hosts_cs); return; } @@ -220,6 +239,8 @@ void add_host(const unsigned char *net, const unsigned char *node, uint32_t ipad hptr = malloc(sizeof(ipx_host)); if(!hptr) { + LeaveCriticalSection(&hosts_cs); + log_printf("No memory for hosts list entry"); return; } @@ -232,10 +253,14 @@ void add_host(const unsigned char *net, const unsigned char *node, uint32_t ipad hptr->next = hosts; hosts = hptr; + + LeaveCriticalSection(&hosts_cs); } /* Search the hosts list */ ipx_host *find_host(const unsigned char *net, const unsigned char *node) { + EnterCriticalSection(&hosts_cs); + ipx_host *hptr = hosts, *pptr = NULL; while(hptr) { @@ -251,15 +276,16 @@ ipx_host *find_host(const unsigned char *net, const unsigned char *node) { free(hptr); } - return NULL; - }else{ - return hptr; + hptr = NULL; } + + break; } pptr = hptr; hptr = hptr->next; } - return NULL; + LeaveCriticalSection(&hosts_cs); + return hptr; } diff --git a/src/ipxwrapper.h b/src/ipxwrapper.h index ecb675d..0c5b2ec 100644 --- a/src/ipxwrapper.h +++ b/src/ipxwrapper.h @@ -41,19 +41,14 @@ #define IPX_EX_BOUND (int)(1<<5) #define RETURN(...) \ - unlock_mutex();\ + unlock_sockets();\ return __VA_ARGS__; #define RETURN_WSA(errnum, ...) \ - unlock_mutex();\ + unlock_sockets();\ WSASetLastError(errnum);\ return __VA_ARGS__; -#define RETURN_ERR(errnum, ...) \ - unlock_mutex();\ - SetLastError(errnum);\ - return __VA_ARGS__; - typedef struct ipx_socket ipx_socket; typedef struct ipx_packet ipx_packet; typedef struct ipx_host ipx_host; @@ -116,8 +111,8 @@ extern HMODULE wsock32_dll; void __stdcall *find_sym(char const *sym); ipx_socket *get_socket(SOCKET fd); -void lock_mutex(void); -void unlock_mutex(void); +void lock_sockets(void); +void unlock_sockets(void); ipx_host *find_host(const unsigned char *net, const unsigned char *node); void add_host(const unsigned char *net, const unsigned char *node, uint32_t ipaddr); diff --git a/src/winsock.c b/src/winsock.c index 092944d..94f0d58 100644 --- a/src/winsock.c +++ b/src/winsock.c @@ -102,7 +102,8 @@ SOCKET WSAAPI socket(int af, int type, int protocol) { if(af == AF_IPX) { ipx_socket *nsock = malloc(sizeof(ipx_socket)); if(!nsock) { - RETURN_WSA(ERROR_OUTOFMEMORY, -1); + WSASetLastError(ERROR_OUTOFMEMORY); + return -1; } nsock->fd = r_socket(AF_INET, SOCK_DGRAM, 0); @@ -110,13 +111,13 @@ SOCKET WSAAPI socket(int af, int type, int protocol) { log_printf("Creating fake socket failed: %s", w32_error(WSAGetLastError())); free(nsock); - RETURN(-1); + return -1; } nsock->flags = IPX_SEND | IPX_RECV; nsock->s_ptype = (protocol ? NSPROTO_IPX - protocol : 0); - lock_mutex(); + lock_sockets(); nsock->next = sockets; sockets = nsock; @@ -226,7 +227,7 @@ int WSAAPI bind(SOCKET fd, const struct sockaddr *addr, int addrlen) { RETURN(0); }else{ - RETURN(r_bind(fd, addr, addrlen)); + return r_bind(fd, addr, addrlen); } } @@ -255,7 +256,7 @@ int WSAAPI getsockname(SOCKET fd, struct sockaddr *addr, int *addrlen) { RETURN_WSA(WSAEINVAL, -1); } }else{ - RETURN(r_getsockname(fd, addr, addrlen)); + return r_getsockname(fd, addr, addrlen); } } @@ -269,7 +270,7 @@ static int recv_packet(ipx_socket *sockptr, char *buf, int bufsize, int flags, s SOCKET fd = sockptr->fd; int is_bound = sockptr->flags & IPX_BOUND; - unlock_mutex(); + unlock_sockets(); if(!is_bound) { WSASetLastError(WSAEINVAL); @@ -318,7 +319,7 @@ int WSAAPI recvfrom(SOCKET fd, char *buf, int len, int flags, struct sockaddr *a if(sockptr) { if(addr && addrlen && *addrlen < sizeof(struct sockaddr_ipx)) { - unlock_mutex(); + unlock_sockets(); WSASetLastError(WSAEFAULT); return -1; @@ -471,9 +472,11 @@ int WSAAPI getsockopt(SOCKET fd, int level, int optname, char FAR *optval, int F RETURN_WSA(WSAENOPROTOOPT, -1); } + + unlock_sockets(); } - RETURN(r_getsockopt(fd, level, optname, optval, optlen)); + return r_getsockopt(fd, level, optname, optval, optlen); } int WSAAPI setsockopt(SOCKET fd, int level, int optname, const char FAR *optval, int optlen) { @@ -520,9 +523,11 @@ int WSAAPI setsockopt(SOCKET fd, int level, int optname, const char FAR *optval, RETURN(0); } } + + unlock_sockets(); } - RETURN(r_setsockopt(fd, level, optname, optval, optlen)); + return r_setsockopt(fd, level, optname, optval, optlen); } int WSAAPI sendto(SOCKET fd, const char *buf, int len, int flags, const struct sockaddr *addr, int addrlen) { @@ -599,7 +604,7 @@ int WSAAPI sendto(SOCKET fd, const char *buf, int len, int flags, const struct s free(packet); RETURN(len); }else{ - RETURN(r_sendto(fd, buf, len, flags, addr, addrlen)); + return r_sendto(fd, buf, len, flags, addr, addrlen); } } @@ -618,7 +623,7 @@ int PASCAL shutdown(SOCKET fd, int cmd) { RETURN(0); }else{ - RETURN(r_shutdown(fd, cmd)); + return r_shutdown(fd, cmd); } } @@ -648,7 +653,11 @@ int PASCAL ioctlsocket(SOCKET fd, long cmd, u_long *argp) { *(unsigned long*)argp = packet.size; RETURN(0); - }else{ - RETURN(r_ioctlsocket(fd, cmd, argp)); } + + if(sockptr) { + unlock_sockets(); + } + + return r_ioctlsocket(fd, cmd, argp); }