VirtualBox

Ignore:
Timestamp:
Mar 29, 2010 12:39:25 PM (15 years ago)
Author:
vboxsync
Message:

iprt: RTSocket/RTTcp: refcount the sockets the RTDbg* way.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/tcp.cpp

    r27771 r27787  
    132132    RTTHREAD                    Thread;
    133133    /** The server socket. */
    134     RTSOCKET volatile           SockServer;
     134    RTSOCKET volatile           hServerSocket;
    135135    /** The socket to the client currently being serviced.
    136136     * This is NIL_RTSOCKET when no client is serviced. */
    137     RTSOCKET volatile           SockClient;
     137    RTSOCKET volatile           hClientSocket;
    138138    /** The connection function. */
    139139    PFNRTTCPSERVE               pfnServe;
     
    390390                if (pServer)
    391391                {
    392                     pServer->u32Magic   = RTTCPSERVER_MAGIC;
    393                     pServer->enmState   = RTTCPSERVERSTATE_CREATED;
    394                     pServer->Thread     = NIL_RTTHREAD;
    395                     pServer->SockServer = WaitSock;
    396                     pServer->SockClient = NIL_RTSOCKET;
    397                     pServer->pfnServe   = NULL;
    398                     pServer->pvUser     = NULL;
     392                    pServer->u32Magic       = RTTCPSERVER_MAGIC;
     393                    pServer->enmState       = RTTCPSERVERSTATE_CREATED;
     394                    pServer->Thread         = NIL_RTTHREAD;
     395                    pServer->hServerSocket = WaitSock;
     396                    pServer->hClientSocket = NIL_RTSOCKET;
     397                    pServer->pfnServe       = NULL;
     398                    pServer->pvUser         = NULL;
    399399                    *ppServer = pServer;
    400400                    return VINF_SUCCESS;
     
    446446        Assert(!pServer->pvUser);
    447447        Assert(pServer->Thread == NIL_RTTHREAD);
    448         Assert(pServer->SockClient == NIL_RTSOCKET);
     448        Assert(pServer->hClientSocket == NIL_RTSOCKET);
    449449
    450450        pServer->pfnServe = pfnServe;
     
    479479    {
    480480        /*
    481          * Change state.
     481         * Change state, getting an extra reference to the socket so we can
     482         * allow others to close it while we're stuck in rtSocketAccept.
    482483         */
    483         RTTCPSERVERSTATE    enmState   = pServer->enmState;
    484         RTSOCKET            SockServer = pServer->SockServer;
     484        RTTCPSERVERSTATE    enmState      = pServer->enmState;
     485        RTSOCKET            hServerSocket;
     486        ASMAtomicXchgHandle(&pServer->hServerSocket, NIL_RTSOCKET, &hServerSocket);
     487        if (hServerSocket != NIL_RTSOCKET)
     488        {
     489            RTSocketRetain(hServerSocket);
     490            ASMAtomicWriteHandle(&pServer->hServerSocket, hServerSocket);
     491        }
    485492        if (    enmState != RTTCPSERVERSTATE_ACCEPTING
    486493            &&  enmState != RTTCPSERVERSTATE_SERVING)
     494        {
     495            RTSocketRelease(hServerSocket);
    487496            return rtTcpServerListenCleanup(pServer);
     497        }
    488498        if (!rtTcpServerTrySetState(pServer, RTTCPSERVERSTATE_ACCEPTING, enmState))
     499        {
     500            RTSocketRelease(hServerSocket);
    489501            continue;
     502        }
    490503
    491504        /*
     
    494507        struct sockaddr_in  RemoteAddr;
    495508        size_t              cbRemoteAddr = sizeof(RemoteAddr);
    496         RTSOCKET            Socket;
     509        RTSOCKET            hClientSocket;
    497510        RT_ZERO(RemoteAddr);
    498         int rc = rtSocketAccept(SockServer, &Socket, (struct sockaddr *)&RemoteAddr, &cbRemoteAddr);
     511        int rc = rtSocketAccept(hServerSocket, &hClientSocket, (struct sockaddr *)&RemoteAddr, &cbRemoteAddr);
     512        RTSocketRelease(hServerSocket);
    499513        if (RT_FAILURE(rc))
    500514        {
     
    506520            continue;
    507521        }
    508         RTSocketSetInheritance(Socket, false /*fInheritable*/);
     522        RTSocketSetInheritance(hClientSocket, false /*fInheritable*/);
    509523
    510524        /*
     
    513527        if (!rtTcpServerTrySetState(pServer, RTTCPSERVERSTATE_SERVING, RTTCPSERVERSTATE_ACCEPTING))
    514528        {
    515             rtTcpClose(Socket, "rtTcpServerListen", true /*fTryGracefulShutdown*/);
     529            rtTcpClose(hClientSocket, "rtTcpServerListen", true /*fTryGracefulShutdown*/);
    516530            return rtTcpServerListenCleanup(pServer);
    517531        }
    518         rtTcpAtomicXchgSock(&pServer->SockClient, Socket);
    519         rc = pServer->pfnServe(Socket, pServer->pvUser);
    520         rtTcpServerDestroySocket(&pServer->SockClient, "Listener: client", true /*fTryGracefulShutdown*/);
     532        RTSocketRetain(hClientSocket);
     533        rtTcpAtomicXchgSock(&pServer->hClientSocket, hClientSocket);
     534        rc = pServer->pfnServe(hClientSocket, pServer->pvUser);
     535        rtTcpServerDestroySocket(&pServer->hClientSocket, "Listener: client (secondary)", true /*fTryGracefulShutdown*/);
     536        RTSocketRelease(hClientSocket);
    521537
    522538        /*
     
    531547                 * we cannot safely access the handle so we'll have to return here.
    532548                 */
    533                 SockServer = rtTcpAtomicXchgSock(&pServer->SockServer, NIL_RTSOCKET);
     549                hServerSocket = rtTcpAtomicXchgSock(&pServer->hServerSocket, NIL_RTSOCKET);
    534550                rtTcpServerSetState(pServer, RTTCPSERVERSTATE_STOPPED, RTTCPSERVERSTATE_STOPPING);
    535                 rtTcpClose(SockServer, "Listener: server stopped", false /*fTryGracefulShutdown*/);
     551                rtTcpClose(hServerSocket, "Listener: server stopped", false /*fTryGracefulShutdown*/);
    536552            }
    537553            else
     
    551567     * Close the server socket, the client one shouldn't be set.
    552568     */
    553     rtTcpServerDestroySocket(&pServer->SockServer, "ListenCleanup", false /*fTryGracefulShutdown*/);
    554     Assert(pServer->SockClient == NIL_RTSOCKET);
     569    rtTcpServerDestroySocket(&pServer->hServerSocket, "ListenCleanup", false /*fTryGracefulShutdown*/);
     570    Assert(pServer->hClientSocket == NIL_RTSOCKET);
    555571
    556572    /*
     
    590606 *
    591607 * @param   pServer         The server handle as returned from RTTcpServerCreateEx().
    592  * @param   pSockClient     Where to return the socket handle to the client
    593  *                          connection (on success only).  Use
    594  *                          RTTcpServerDisconnectClient() to clean it, this must
    595  *                          be done before the next call to RTTcpServerListen2.
    596  *
    597  * @todo    This can easily be extended to support multiple connections by
    598  *          adding a new state and a RTTcpServerDisconnectClient variant for
    599  *          closing client sockets.
    600  */
    601 RTR3DECL(int) RTTcpServerListen2(PRTTCPSERVER pServer, PRTSOCKET pSockClient)
     608 * @param   phClientSocket  Where to return the socket handle to the client
     609 *                          connection (on success only).  This must be closed
     610 *                          by calling RTTcpServerDisconnectClient2().
     611 */
     612RTR3DECL(int) RTTcpServerListen2(PRTTCPSERVER pServer, PRTSOCKET phClientSocket)
    602613{
    603614    /*
    604615     * Validate input and retain the instance.
    605616     */
    606     AssertPtrReturn(pSockClient, VERR_INVALID_HANDLE);
    607     *pSockClient = NIL_RTSOCKET;
     617    AssertPtrReturn(phClientSocket, VERR_INVALID_HANDLE);
     618    *phClientSocket = NIL_RTSOCKET;
    608619    AssertReturn(pServer->u32Magic == RTTCPSERVER_MAGIC, VERR_INVALID_HANDLE);
    609620    AssertReturn(RTMemPoolRetain(pServer) != UINT32_MAX, VERR_INVALID_HANDLE);
     
    613624    {
    614625        /*
    615          * Change state to accepting.
     626         * Change state, getting an extra reference to the socket so we can
     627         * allow others to close it while we're stuck in rtSocketAccept.
    616628         */
    617         RTTCPSERVERSTATE    enmState   = pServer->enmState;
    618         RTSOCKET            SockServer = pServer->SockServer;
     629        RTTCPSERVERSTATE    enmState      = pServer->enmState;
     630        RTSOCKET            hServerSocket;
     631        ASMAtomicXchgHandle(&pServer->hServerSocket, NIL_RTSOCKET, &hServerSocket);
     632        if (hServerSocket != NIL_RTSOCKET)
     633        {
     634            RTSocketRetain(hServerSocket);
     635            ASMAtomicWriteHandle(&pServer->hServerSocket, hServerSocket);
     636        }
    619637        if (    enmState != RTTCPSERVERSTATE_SERVING
    620638            &&  enmState != RTTCPSERVERSTATE_CREATED)
    621639        {
    622             rc = rtTcpServerListenCleanup(pServer);
    623             break;
     640            RTSocketRelease(hServerSocket);
     641            return rtTcpServerListenCleanup(pServer);
    624642        }
    625643        if (!rtTcpServerTrySetState(pServer, RTTCPSERVERSTATE_ACCEPTING, enmState))
     644        {
     645            RTSocketRelease(hServerSocket);
    626646            continue;
     647        }
    627648        Assert(!pServer->pfnServe);
    628649        Assert(!pServer->pvUser);
    629650        Assert(pServer->Thread == NIL_RTTHREAD);
    630         Assert(pServer->SockClient == NIL_RTSOCKET);
     651        Assert(pServer->hClientSocket == NIL_RTSOCKET);
    631652
    632653        /*
     
    635656        struct sockaddr_in  RemoteAddr;
    636657        size_t              cbRemoteAddr = sizeof(RemoteAddr);
    637         RTSOCKET            Socket;
     658        RTSOCKET            hClientSocket;
    638659        RT_ZERO(RemoteAddr);
    639         rc = rtSocketAccept(SockServer, &Socket, (struct sockaddr *)&RemoteAddr, &cbRemoteAddr);
     660        rc = rtSocketAccept(hServerSocket, &hClientSocket, (struct sockaddr *)&RemoteAddr, &cbRemoteAddr);
     661        RTSocketRelease(hServerSocket);
    640662        if (RT_FAILURE(rc))
    641663        {
     
    646668            continue;
    647669        }
    648         RTSocketSetInheritance(Socket, false /*fInheritable*/);
     670        RTSocketSetInheritance(hClientSocket, false /*fInheritable*/);
    649671
    650672        /*
     
    653675        if (rtTcpServerTrySetState(pServer, RTTCPSERVERSTATE_SERVING, RTTCPSERVERSTATE_ACCEPTING))
    654676        {
    655             RTSOCKET OldSocket = rtTcpAtomicXchgSock(&pServer->SockClient, Socket);
    656             Assert(OldSocket == NIL_RTSOCKET); NOREF(OldSocket);
    657             *pSockClient = Socket;
     677            *phClientSocket = hClientSocket;
    658678            rc = VINF_SUCCESS;
    659679        }
    660680        else
    661681        {
    662             rtTcpClose(Socket, "RTTcpServerListen2", true /*fTryGracefulShutdown*/);
     682            rtTcpClose(hClientSocket, "RTTcpServerListen2", true /*fTryGracefulShutdown*/);
    663683            rc = rtTcpServerListenCleanup(pServer);
    664684        }
     
    686706    AssertReturn(RTMemPoolRetain(pServer) != UINT32_MAX, VERR_INVALID_HANDLE);
    687707
    688     int rc = rtTcpServerDestroySocket(&pServer->SockClient, "DisconnectClient: client", true /*fTryGracefulShutdown*/);
     708    int rc = rtTcpServerDestroySocket(&pServer->hClientSocket, "DisconnectClient: client", true /*fTryGracefulShutdown*/);
    689709
    690710    RTMemPoolRelease(RTMEMPOOL_DEFAULT, pServer);
    691711    return rc;
     712}
     713
     714
     715/**
     716 * Terminates an open client connect when using RTTcpListen2
     717 *
     718 * @returns IPRT status code.
     719 * @param   hClientSocket   The client socket handle.  This will be invalid upon
     720 *                          return, whether successful or not.  NIL is quietly
     721 *                          ignored (VINF_SUCCESS).
     722 */
     723RTR3DECL(int) RTTcpServerDisconnectClient2(RTSOCKET hClientSocket)
     724{
     725    return rtTcpClose(hClientSocket, "RTTcpServerDisconnectClient2", true /*fTryGracefulShutdown*/);
    692726}
    693727
     
    736770        if (rtTcpServerTrySetState(pServer, RTTCPSERVERSTATE_STOPPING, enmState))
    737771        {
    738             rtTcpServerDestroySocket(&pServer->SockServer, "RTTcpServerShutdown", false /*fTryGracefulShutdown*/);
     772            rtTcpServerDestroySocket(&pServer->hServerSocket, "RTTcpServerShutdown", false /*fTryGracefulShutdown*/);
    739773            rtTcpServerSetState(pServer, RTTCPSERVERSTATE_STOPPED, RTTCPSERVERSTATE_STOPPING);
    740774
     
    800834     */
    801835    ASMAtomicWriteU32(&pServer->u32Magic, ~RTTCPSERVER_MAGIC);
    802     rtTcpServerDestroySocket(&pServer->SockServer, "Destroyer: server", false /*fTryGracefulShutdown*/);
    803     rtTcpServerDestroySocket(&pServer->SockClient, "Destroyer: client", true  /*fTryGracefulShutdown*/);
     836    rtTcpServerDestroySocket(&pServer->hServerSocket, "Destroyer: server", false /*fTryGracefulShutdown*/);
     837    rtTcpServerDestroySocket(&pServer->hClientSocket, "Destroyer: client", true  /*fTryGracefulShutdown*/);
    804838
    805839    /*
     
    930964
    931965    /*
    932      * Destroy the socket handle.
    933      */
    934     return RTSocketDestroy(Sock);
     966     * Close the socket handle (drops our reference to it).
     967     */
     968    return RTSocketClose(Sock);
    935969}
    936970
Note: See TracChangeset for help on using the changeset viewer.

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