Changeset 27787 in vbox for trunk/src/VBox/Runtime/r3/tcp.cpp
- Timestamp:
- Mar 29, 2010 12:39:25 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/tcp.cpp
r27771 r27787 132 132 RTTHREAD Thread; 133 133 /** The server socket. */ 134 RTSOCKET volatile SockServer;134 RTSOCKET volatile hServerSocket; 135 135 /** The socket to the client currently being serviced. 136 136 * This is NIL_RTSOCKET when no client is serviced. */ 137 RTSOCKET volatile SockClient;137 RTSOCKET volatile hClientSocket; 138 138 /** The connection function. */ 139 139 PFNRTTCPSERVE pfnServe; … … 390 390 if (pServer) 391 391 { 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; 399 399 *ppServer = pServer; 400 400 return VINF_SUCCESS; … … 446 446 Assert(!pServer->pvUser); 447 447 Assert(pServer->Thread == NIL_RTTHREAD); 448 Assert(pServer-> SockClient == NIL_RTSOCKET);448 Assert(pServer->hClientSocket == NIL_RTSOCKET); 449 449 450 450 pServer->pfnServe = pfnServe; … … 479 479 { 480 480 /* 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. 482 483 */ 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 } 485 492 if ( enmState != RTTCPSERVERSTATE_ACCEPTING 486 493 && enmState != RTTCPSERVERSTATE_SERVING) 494 { 495 RTSocketRelease(hServerSocket); 487 496 return rtTcpServerListenCleanup(pServer); 497 } 488 498 if (!rtTcpServerTrySetState(pServer, RTTCPSERVERSTATE_ACCEPTING, enmState)) 499 { 500 RTSocketRelease(hServerSocket); 489 501 continue; 502 } 490 503 491 504 /* … … 494 507 struct sockaddr_in RemoteAddr; 495 508 size_t cbRemoteAddr = sizeof(RemoteAddr); 496 RTSOCKET Socket;509 RTSOCKET hClientSocket; 497 510 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); 499 513 if (RT_FAILURE(rc)) 500 514 { … … 506 520 continue; 507 521 } 508 RTSocketSetInheritance( Socket, false /*fInheritable*/);522 RTSocketSetInheritance(hClientSocket, false /*fInheritable*/); 509 523 510 524 /* … … 513 527 if (!rtTcpServerTrySetState(pServer, RTTCPSERVERSTATE_SERVING, RTTCPSERVERSTATE_ACCEPTING)) 514 528 { 515 rtTcpClose( Socket, "rtTcpServerListen", true /*fTryGracefulShutdown*/);529 rtTcpClose(hClientSocket, "rtTcpServerListen", true /*fTryGracefulShutdown*/); 516 530 return rtTcpServerListenCleanup(pServer); 517 531 } 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); 521 537 522 538 /* … … 531 547 * we cannot safely access the handle so we'll have to return here. 532 548 */ 533 SockServer = rtTcpAtomicXchgSock(&pServer->SockServer, NIL_RTSOCKET);549 hServerSocket = rtTcpAtomicXchgSock(&pServer->hServerSocket, NIL_RTSOCKET); 534 550 rtTcpServerSetState(pServer, RTTCPSERVERSTATE_STOPPED, RTTCPSERVERSTATE_STOPPING); 535 rtTcpClose( SockServer, "Listener: server stopped", false /*fTryGracefulShutdown*/);551 rtTcpClose(hServerSocket, "Listener: server stopped", false /*fTryGracefulShutdown*/); 536 552 } 537 553 else … … 551 567 * Close the server socket, the client one shouldn't be set. 552 568 */ 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); 555 571 556 572 /* … … 590 606 * 591 607 * @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 */ 612 RTR3DECL(int) RTTcpServerListen2(PRTTCPSERVER pServer, PRTSOCKET phClientSocket) 602 613 { 603 614 /* 604 615 * Validate input and retain the instance. 605 616 */ 606 AssertPtrReturn(p SockClient, VERR_INVALID_HANDLE);607 *p SockClient = NIL_RTSOCKET;617 AssertPtrReturn(phClientSocket, VERR_INVALID_HANDLE); 618 *phClientSocket = NIL_RTSOCKET; 608 619 AssertReturn(pServer->u32Magic == RTTCPSERVER_MAGIC, VERR_INVALID_HANDLE); 609 620 AssertReturn(RTMemPoolRetain(pServer) != UINT32_MAX, VERR_INVALID_HANDLE); … … 613 624 { 614 625 /* 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. 616 628 */ 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 } 619 637 if ( enmState != RTTCPSERVERSTATE_SERVING 620 638 && enmState != RTTCPSERVERSTATE_CREATED) 621 639 { 622 rc = rtTcpServerListenCleanup(pServer);623 break;640 RTSocketRelease(hServerSocket); 641 return rtTcpServerListenCleanup(pServer); 624 642 } 625 643 if (!rtTcpServerTrySetState(pServer, RTTCPSERVERSTATE_ACCEPTING, enmState)) 644 { 645 RTSocketRelease(hServerSocket); 626 646 continue; 647 } 627 648 Assert(!pServer->pfnServe); 628 649 Assert(!pServer->pvUser); 629 650 Assert(pServer->Thread == NIL_RTTHREAD); 630 Assert(pServer-> SockClient == NIL_RTSOCKET);651 Assert(pServer->hClientSocket == NIL_RTSOCKET); 631 652 632 653 /* … … 635 656 struct sockaddr_in RemoteAddr; 636 657 size_t cbRemoteAddr = sizeof(RemoteAddr); 637 RTSOCKET Socket;658 RTSOCKET hClientSocket; 638 659 RT_ZERO(RemoteAddr); 639 rc = rtSocketAccept(SockServer, &Socket, (struct sockaddr *)&RemoteAddr, &cbRemoteAddr); 660 rc = rtSocketAccept(hServerSocket, &hClientSocket, (struct sockaddr *)&RemoteAddr, &cbRemoteAddr); 661 RTSocketRelease(hServerSocket); 640 662 if (RT_FAILURE(rc)) 641 663 { … … 646 668 continue; 647 669 } 648 RTSocketSetInheritance( Socket, false /*fInheritable*/);670 RTSocketSetInheritance(hClientSocket, false /*fInheritable*/); 649 671 650 672 /* … … 653 675 if (rtTcpServerTrySetState(pServer, RTTCPSERVERSTATE_SERVING, RTTCPSERVERSTATE_ACCEPTING)) 654 676 { 655 RTSOCKET OldSocket = rtTcpAtomicXchgSock(&pServer->SockClient, Socket); 656 Assert(OldSocket == NIL_RTSOCKET); NOREF(OldSocket); 657 *pSockClient = Socket; 677 *phClientSocket = hClientSocket; 658 678 rc = VINF_SUCCESS; 659 679 } 660 680 else 661 681 { 662 rtTcpClose( Socket, "RTTcpServerListen2", true /*fTryGracefulShutdown*/);682 rtTcpClose(hClientSocket, "RTTcpServerListen2", true /*fTryGracefulShutdown*/); 663 683 rc = rtTcpServerListenCleanup(pServer); 664 684 } … … 686 706 AssertReturn(RTMemPoolRetain(pServer) != UINT32_MAX, VERR_INVALID_HANDLE); 687 707 688 int rc = rtTcpServerDestroySocket(&pServer-> SockClient, "DisconnectClient: client", true /*fTryGracefulShutdown*/);708 int rc = rtTcpServerDestroySocket(&pServer->hClientSocket, "DisconnectClient: client", true /*fTryGracefulShutdown*/); 689 709 690 710 RTMemPoolRelease(RTMEMPOOL_DEFAULT, pServer); 691 711 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 */ 723 RTR3DECL(int) RTTcpServerDisconnectClient2(RTSOCKET hClientSocket) 724 { 725 return rtTcpClose(hClientSocket, "RTTcpServerDisconnectClient2", true /*fTryGracefulShutdown*/); 692 726 } 693 727 … … 736 770 if (rtTcpServerTrySetState(pServer, RTTCPSERVERSTATE_STOPPING, enmState)) 737 771 { 738 rtTcpServerDestroySocket(&pServer-> SockServer, "RTTcpServerShutdown", false /*fTryGracefulShutdown*/);772 rtTcpServerDestroySocket(&pServer->hServerSocket, "RTTcpServerShutdown", false /*fTryGracefulShutdown*/); 739 773 rtTcpServerSetState(pServer, RTTCPSERVERSTATE_STOPPED, RTTCPSERVERSTATE_STOPPING); 740 774 … … 800 834 */ 801 835 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*/); 804 838 805 839 /* … … 930 964 931 965 /* 932 * Destroy the socket handle.933 */ 934 return RTSocket Destroy(Sock);966 * Close the socket handle (drops our reference to it). 967 */ 968 return RTSocketClose(Sock); 935 969 } 936 970
Note:
See TracChangeset
for help on using the changeset viewer.