VirtualBox

忽略:
時間撮記:
2009-10-30 下午04:00:40 (15 年 以前)
作者:
vboxsync
訊息:

IPRT/r3/tcp.cpp: correct shutdown sequence.

檔案:
修改 1 筆資料

圖例:

未更動
新增
刪除
  • trunk/src/VBox/Runtime/r3/tcp.cpp

    r23666 r24204  
    5656#include <iprt/string.h>
    5757#include <iprt/thread.h>
     58#include <iprt/time.h>
    5859
    5960#include "internal/magics.h"
     
    7273# else
    7374#  define SHUT_RDWR             2
     75# endif
     76#endif
     77#ifndef SHUT_WR
     78# ifdef SD_SEND
     79#  define SHUT_WR               SD_SEND
     80# else
     81#  define SHUT_WR               1
    7482# endif
    7583#endif
     
    140148static int  rcTcpServerListenCleanup(PRTTCPSERVER pServer);
    141149static int  rtTcpServerDestroySocket(RTSOCKET volatile *pSockClient, const char *pszMsg);
    142 static int  rtTcpClose(RTSOCKET Sock, const char *pszMsg);
     150static int  rtTcpClose(RTSOCKET Sock, const char *pszMsg, bool fTryGracefulShutdown);
    143151
    144152
     
    243251 * @returns IPRT status code.
    244252 */
    245 static int rtTcpServerDestroySocket(RTSOCKET volatile *pSock, const char *pszMsg)
     253static int rtTcpServerDestroySocket(RTSOCKET volatile *pSock, const char *pszMsg, bool fTryGracefulShutdown)
    246254{
    247255    RTSOCKET Sock = rtTcpAtomicXchgSock(pSock, NIL_RTSOCKET);
    248256    if (Sock != NIL_RTSOCKET)
    249257    {
    250         shutdown(Sock, SHUT_RDWR);
    251         return rtTcpClose(Sock, pszMsg);
     258        if (!fTryGracefulShutdown)
     259            shutdown(Sock, SHUT_RDWR);
     260        return rtTcpClose(Sock, pszMsg, fTryGracefulShutdown);
    252261    }
    253262    return VINF_TCP_SERVER_NO_CLIENT;
     
    467476            AssertMsgFailed(("setsockopt() %Rrc\n", rc));
    468477        }
    469         rtTcpClose(WaitSock, "RTServerCreateEx");
     478        rtTcpClose(WaitSock, "RTServerCreateEx", false /*fTryGracefulShutdown*/);
    470479    }
    471480    else
     
    575584        if (!rtTcpServerTrySetState(pServer, RTTCPSERVERSTATE_SERVING, RTTCPSERVERSTATE_ACCEPTING))
    576585        {
    577             rtTcpClose(Socket, "rtTcpServerListen");
     586            rtTcpClose(Socket, "rtTcpServerListen", true /*fTryGracefulShutdown*/);
    578587            return rcTcpServerListenCleanup(pServer);
    579588        }
    580589        rtTcpAtomicXchgSock(&pServer->SockClient, Socket);
    581590        int rc = pServer->pfnServe(Socket, pServer->pvUser);
    582         rtTcpServerDestroySocket(&pServer->SockClient, "Listener: client");
     591        rtTcpServerDestroySocket(&pServer->SockClient, "Listener: client", true /*fTryGracefulShutdown*/);
    583592
    584593        /*
     
    595604                RTSOCKET SockServer = rtTcpAtomicXchgSock(&pServer->SockServer, NIL_RTSOCKET);
    596605                rtTcpServerSetState(pServer, RTTCPSERVERSTATE_STOPPED, RTTCPSERVERSTATE_STOPPING);
    597                 rtTcpClose(SockServer, "Listener: server stopped");
     606                rtTcpClose(SockServer, "Listener: server stopped", false /*fTryGracefulShutdown*/);
    598607            }
    599608            else
     
    613622     * Close the server socket, the client one shouldn't be set.
    614623     */
    615     rtTcpServerDestroySocket(&pServer->SockServer, "ListenCleanup");
     624    rtTcpServerDestroySocket(&pServer->SockServer, "ListenCleanup", false /*fTryGracefulShutdown*/);
    616625    Assert(pServer->SockClient == NIL_RTSOCKET);
    617626
     
    656665    AssertReturn(RTMemPoolRetain(pServer) != UINT32_MAX, VERR_INVALID_HANDLE);
    657666
    658     int rc = rtTcpServerDestroySocket(&pServer->SockClient, "DisconnectClient: client");
     667    int rc = rtTcpServerDestroySocket(&pServer->SockClient, "DisconnectClient: client", true /*fTryGracefulShutdown*/);
    659668
    660669    RTMemPoolRelease(RTMEMPOOL_DEFAULT, pServer);
     
    706715        if (rtTcpServerTrySetState(pServer, RTTCPSERVERSTATE_STOPPING, enmState))
    707716        {
    708             rtTcpServerDestroySocket(&pServer->SockServer, "RTTcpServerShutdown");
     717            rtTcpServerDestroySocket(&pServer->SockServer, "RTTcpServerShutdown", false /*fTryGracefulShutdown*/);
    709718            rtTcpServerSetState(pServer, RTTCPSERVERSTATE_STOPPED, RTTCPSERVERSTATE_STOPPING);
    710719
     
    770779     */
    771780    ASMAtomicWriteU32(&pServer->u32Magic, ~RTTCPSERVER_MAGIC);
    772     rtTcpServerDestroySocket(&pServer->SockServer, "Destroyer: server");
    773     rtTcpServerDestroySocket(&pServer->SockClient, "Destroyer: client");
     781    rtTcpServerDestroySocket(&pServer->SockServer, "Destroyer: server", false /*fTryGracefulShutdown*/);
     782    rtTcpServerDestroySocket(&pServer->SockClient, "Destroyer: client", true  /*fTryGracefulShutdown*/);
    774783
    775784    /*
     
    945954        }
    946955        rc = rtTcpError();
    947         rtTcpClose(Sock, "RTTcpClientConnect");
     956        rtTcpClose(Sock, "RTTcpClientConnect", false /*fTryGracefulShutdown*/);
    948957    }
    949958    else
     
    955964RTR3DECL(int) RTTcpClientClose(RTSOCKET Sock)
    956965{
    957     return rtTcpClose(Sock, "RTTcpClientClose");
     966    return rtTcpClose(Sock, "RTTcpClientClose", true /*fTryGracefulShutdown*/);
    958967}
    959968
     
    962971 * Internal close function which does all the proper bitching.
    963972 */
    964 static int rtTcpClose(RTSOCKET Sock, const char *pszMsg)
    965 {
     973static int rtTcpClose(RTSOCKET Sock, const char *pszMsg, bool fTryGracefulShutdown)
     974{
     975    int rc;
     976
    966977    /* ignore nil handles. */
    967978    if (Sock == NIL_RTSOCKET)
     
    969980
    970981    /*
     982     * Try to gracefully shut it down.
     983     */
     984    if (fTryGracefulShutdown)
     985    {
     986        rc = shutdown(Sock, SHUT_WR);
     987        if (!rc)
     988        {
     989            uint64_t u64Start = RTTimeMilliTS();
     990            for (;;)
     991            {
     992                rc = RTTcpSelectOne(Sock, 1000);
     993                if (rc == VERR_TIMEOUT)
     994                {
     995                    if (RTTimeMilliTS() - u64Start > 30000)
     996                        break;
     997                }
     998                else if (rc != VINF_SUCCESS)
     999                    break;
     1000                {
     1001                    uint8_t abBitBucket[16*_1KB];
     1002                    ssize_t cbBytesRead = recv(Sock, abBitBucket, sizeof(abBitBucket), MSG_NOSIGNAL);
     1003                    if (cbBytesRead == 0)
     1004                        break; /* orderly shutdown in progress */
     1005                    if (cbBytesRead < 0)
     1006                        break; /* some kind of error, never mind which... */
     1007                }
     1008            }  /* forever */
     1009        }
     1010    }
     1011
     1012    /*
    9711013     * Attempt to close it.
    9721014     */
    9731015#ifdef RT_OS_WINDOWS
    974     int rc = closesocket(Sock);
     1016    rc = closesocket(Sock);
    9751017#else
    976     int rc = close(Sock);
     1018    rc = close(Sock);
    9771019#endif
    9781020    if (!rc)
注意: 瀏覽 TracChangeset 來幫助您使用更動檢視器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette