From: Oliver Kurth Date: Fri, 15 Sep 2017 18:23:45 +0000 (-0700) Subject: AsyncSocket: X-Git-Tag: stable-10.2.0~153 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4e7e626ceef413b02c3831cc25f70be970bc9829;p=thirdparty%2Fopen-vm-tools.git AsyncSocket: - Fix issue where the listening socket becomes bad and the callback function is invoked unexpectedly. - Change not directly applicable to open-vm-tools. --- diff --git a/open-vm-tools/lib/asyncsocket/asyncsocket.c b/open-vm-tools/lib/asyncsocket/asyncsocket.c index d2086fc67..13908679b 100644 --- a/open-vm-tools/lib/asyncsocket/asyncsocket.c +++ b/open-vm-tools/lib/asyncsocket/asyncsocket.c @@ -364,6 +364,9 @@ static int AsyncTCPSocketGetOption(AsyncSocket *asyncSocket, AsyncSocketOpts_ID optID, void *valuePtr, socklen_t *outBufLen); +static void AsyncTCPSocketListenerError(int error, + AsyncSocket *asock, + void *clientData); /* Local constants. */ @@ -1083,6 +1086,12 @@ AsyncSocket_Listen(const char *addrStr, // IN: optional AsyncTCPSocketSetState(asock, AsyncSocketListening); asock->listenAsock6 = asock6; asock->listenAsock4 = asock4; + AsyncSocket_SetErrorFn(BaseSocket(asock4), + AsyncTCPSocketListenerError, + asock); + AsyncSocket_SetErrorFn(BaseSocket(asock6), + AsyncTCPSocketListenerError, + asock); return BaseSocket(asock); } else if (asock6) { @@ -3557,8 +3566,18 @@ AsyncTCPSocketAcceptInternal(AsyncTCPSocket *s) // IN s->genericErrno = sysErr; if (sysErr == ASOCK_EWOULDBLOCK) { TCPSOCKWARN(s, ("spurious accept notification\n")); - +#if TARGET_OS_IPHONE + /* + * For iOS, while the app is suspended and device's screen is locked, + * system will reclaim resources from underneath socket(see Apple + * Technical Note TN2277), the callback function AsyncTCPSocketAcceptCallback() + * will be invoked repeatedly, to deal with this issue, we need to + * handle error EWOULDBLOCK. + */ + return ASOCKERR_ACCEPT; +#else return ASOCKERR_GENERIC; +#endif #ifndef _WIN32 /* * This sucks. Linux accept() can return ECONNABORTED for connections @@ -4373,7 +4392,6 @@ static int AsyncTCPSocketClose(AsyncSocket *base) // IN { AsyncTCPSocket *asock = TCPSocket(base); - Bool isListener = TRUE; ASSERT(AsyncTCPSocketIsLocked(asock)); @@ -4393,8 +4411,6 @@ AsyncTCPSocketClose(AsyncSocket *base) // IN Bool removed; AsyncSocketState oldState; - isListener = FALSE; - /* Flush output if requested via AsyncTCPSocket_SetCloseOptions(). */ if (asock->flushEnabledMaxWaitMsec && AsyncTCPSocketGetState(asock) == AsyncSocketConnected && @@ -5875,3 +5891,32 @@ AsyncSocket_ListenSocketUDS(const char *pipeName, // IN return BaseSocket(asock); } #endif + + +/* + *----------------------------------------------------------------------------- + * + * AsyncTCPSocketListenerError -- + * + * Call the error handler from parent AsyncSocket object. The passed in + * parameter clientData is the parent AsyncSocket object. + * + * Result + * None + * + * Side-effects + * None + * + *----------------------------------------------------------------------------- + */ + +static void +AsyncTCPSocketListenerError(int error, // IN + AsyncSocket *asock, // IN + void *clientData) // IN +{ + AsyncSocket *s = clientData; + ASSERT(s); + + AsyncSocketHandleError(s, error); +}