mirror of
https://github.com/solemnwarning/ipxwrapper
synced 2024-12-30 16:45:37 +01:00
DirectPlay: Refactor worker loop.
Hold the lock while reading to ensure the socket isn't closed during the recvfrom() call, allow either socket to be closed and close either socket if the recvfrom() call fails.
This commit is contained in:
parent
a89948c2f9
commit
8ded8da35a
@ -66,30 +66,55 @@ static void release_sp_data(struct sp_data *data) {
|
|||||||
LeaveCriticalSection(&(data->lock));
|
LeaveCriticalSection(&(data->lock));
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL recv_packet(int sockfd, char *buf, IDirectPlaySP *sp) {
|
static void recv_packet(SOCKET *sockfd, char *buf, IDirectPlaySP *sp)
|
||||||
|
{
|
||||||
|
struct sp_data *sp_data = get_sp_data((IDirectPlaySP*)(sp));
|
||||||
|
|
||||||
|
if(*sockfd == -1)
|
||||||
|
{
|
||||||
|
release_sp_data(sp_data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
struct sockaddr_ipx addr;
|
struct sockaddr_ipx addr;
|
||||||
int addrlen = sizeof(addr);
|
int addrlen = sizeof(addr);
|
||||||
|
|
||||||
int r = recvfrom(sockfd, buf, MAX_DATA_SIZE, 0, (struct sockaddr*)&addr, &addrlen);
|
int size = recvfrom(*sockfd, buf, MAX_DATA_SIZE, 0, (struct sockaddr*)(&addr), &addrlen);
|
||||||
if(r == -1) {
|
if(size == -1)
|
||||||
if(WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAECONNRESET) {
|
{
|
||||||
return TRUE;
|
if(WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAECONNRESET)
|
||||||
|
{
|
||||||
|
/* WSAEWOULDBLOCK - No packets waiting on this socket.
|
||||||
|
* WSAECONNRESET - We got an ICMP error on this port.
|
||||||
|
*/
|
||||||
|
release_sp_data(sp_data);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_printf(LOG_ERROR, "Read error (IPX): %s", w32_error(WSAGetLastError()));
|
log_printf(LOG_ERROR, "DirectPlay read error: %s", w32_error(WSAGetLastError()));
|
||||||
return FALSE;
|
log_printf(LOG_DEBUG, "Closing socket %u", (unsigned int)(*sockfd));
|
||||||
|
|
||||||
|
closesocket(*sockfd);
|
||||||
|
*sockfd = -1;
|
||||||
|
|
||||||
|
release_sp_data(sp_data);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT h = IDirectPlaySP_HandleMessage(sp, buf, r, &addr);
|
release_sp_data(sp_data);
|
||||||
if(h != DP_OK) {
|
|
||||||
log_printf(LOG_ERROR, "HandleMessage error: %d", (int)h);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
/* Pass the message on to DirectPlay to be processed. */
|
||||||
|
|
||||||
|
IPX_STRING_ADDR(str_addr, addr32_in(addr.sa_netnum), addr48_in(addr.sa_nodenum), addr.sa_socket);
|
||||||
|
log_printf(LOG_DEBUG, "About to HandleMessage from %s", str_addr);
|
||||||
|
|
||||||
|
HRESULT r = IDirectPlaySP_HandleMessage(sp, buf, size, &addr);
|
||||||
|
|
||||||
|
log_printf(LOG_DEBUG, "HandleMessage returned %x", (unsigned int)(r));
|
||||||
}
|
}
|
||||||
|
|
||||||
static DWORD WINAPI worker_main(LPVOID sp) {
|
static DWORD WINAPI worker_main(LPVOID sp) {
|
||||||
struct sp_data *sp_data = get_sp_data((IDirectPlaySP*)sp);
|
struct sp_data *sp_data = get_sp_data((IDirectPlaySP*)(sp));
|
||||||
release_sp_data(sp_data);
|
release_sp_data(sp_data);
|
||||||
|
|
||||||
char *buf = malloc(MAX_DATA_SIZE);
|
char *buf = malloc(MAX_DATA_SIZE);
|
||||||
@ -100,32 +125,22 @@ static DWORD WINAPI worker_main(LPVOID sp) {
|
|||||||
while(1) {
|
while(1) {
|
||||||
WaitForSingleObject(sp_data->event, INFINITE);
|
WaitForSingleObject(sp_data->event, INFINITE);
|
||||||
|
|
||||||
get_sp_data((IDirectPlaySP*)sp);
|
get_sp_data((IDirectPlaySP*)(sp));
|
||||||
|
|
||||||
WSAResetEvent(sp_data->event);
|
WSAResetEvent(sp_data->event);
|
||||||
|
|
||||||
if(!sp_data->running) {
|
if(!sp_data->running)
|
||||||
release_sp_data(sp_data);
|
{
|
||||||
return 0;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
release_sp_data(sp_data);
|
release_sp_data(sp_data);
|
||||||
|
|
||||||
if(!recv_packet(sp_data->sock, buf, sp)) {
|
recv_packet(&(sp_data->sock), buf, sp);
|
||||||
return 1;
|
recv_packet(&(sp_data->ns_sock), buf, sp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sp_data->ns_sock != -1 && !recv_packet(sp_data->ns_sock, buf, sp)) {
|
free(buf);
|
||||||
log_printf(LOG_ERROR, "Closing ns_sock due to error");
|
|
||||||
|
|
||||||
get_sp_data((IDirectPlaySP*)sp);
|
|
||||||
|
|
||||||
closesocket(sp_data->ns_sock);
|
|
||||||
sp_data->ns_sock = -1;
|
|
||||||
|
|
||||||
release_sp_data(sp_data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user