summaryrefslogtreecommitdiff
path: root/src/VBox/Runtime/r3/tcp.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Runtime/r3/tcp.cpp')
-rw-r--r--src/VBox/Runtime/r3/tcp.cpp48
1 files changed, 46 insertions, 2 deletions
diff --git a/src/VBox/Runtime/r3/tcp.cpp b/src/VBox/Runtime/r3/tcp.cpp
index 151dee86..7c6b2ef4 100644
--- a/src/VBox/Runtime/r3/tcp.cpp
+++ b/src/VBox/Runtime/r3/tcp.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -805,11 +805,19 @@ RTR3DECL(int) RTTcpServerDestroy(PRTTCPSERVER pServer)
RTR3DECL(int) RTTcpClientConnect(const char *pszAddress, uint32_t uPort, PRTSOCKET pSock)
{
+ return RTTcpClientConnectEx(pszAddress, uPort, pSock, NULL);
+}
+
+
+RTR3DECL(int) RTTcpClientConnectEx(const char *pszAddress, uint32_t uPort, PRTSOCKET pSock,
+ PRTTCPCLIENTCONNECTCANCEL volatile *ppCancelCookie)
+{
/*
* Validate input.
*/
AssertReturn(uPort > 0, VERR_INVALID_PARAMETER);
AssertPtrReturn(pszAddress, VERR_INVALID_POINTER);
+ AssertPtrNullReturn(ppCancelCookie, VERR_INVALID_POINTER);
/*
* Resolve the address.
@@ -828,7 +836,25 @@ RTR3DECL(int) RTTcpClientConnect(const char *pszAddress, uint32_t uPort, PRTSOCK
{
RTSocketSetInheritance(Sock, false /*fInheritable*/);
- rc = rtSocketConnect(Sock, &Addr);
+ if (!ppCancelCookie)
+ rc = rtSocketConnect(Sock, &Addr);
+ else
+ {
+ RTSocketRetain(Sock);
+ if (ASMAtomicCmpXchgPtr(ppCancelCookie, (PRTTCPCLIENTCONNECTCANCEL)Sock, NULL))
+ {
+ rc = rtSocketConnect(Sock, &Addr);
+ if (ASMAtomicCmpXchgPtr(ppCancelCookie, NULL, (PRTTCPCLIENTCONNECTCANCEL)Sock))
+ RTSocketRelease(Sock);
+ else
+ rc = VERR_CANCELLED;
+ }
+ else
+ {
+ RTSocketRelease(Sock);
+ rc = VERR_CANCELLED;
+ }
+ }
if (RT_SUCCESS(rc))
{
*pSock = Sock;
@@ -837,10 +863,28 @@ RTR3DECL(int) RTTcpClientConnect(const char *pszAddress, uint32_t uPort, PRTSOCK
rtTcpClose(Sock, "RTTcpClientConnect", false /*fTryGracefulShutdown*/);
}
+ if (ppCancelCookie)
+ *ppCancelCookie = NULL;
return rc;
}
+RTR3DECL(int) RTTcpClientCancelConnect(PRTTCPCLIENTCONNECTCANCEL volatile *ppCancelCookie)
+{
+ AssertPtrReturn(ppCancelCookie, VERR_INVALID_POINTER);
+
+ AssertCompile(NIL_RTSOCKET == NULL);
+ RTSOCKET hSock = (RTSOCKET)ASMAtomicXchgPtr((void * volatile *)ppCancelCookie, (void *)(uintptr_t)0xdead9999);
+ if (hSock != NIL_RTSOCKET)
+ {
+ int rc = rtTcpClose(hSock, "RTTcpClientCancelConnect", false /*fTryGracefulShutdown*/);
+ AssertRCReturn(rc, rc);
+ }
+
+ return VINF_SUCCESS;
+}
+
+
RTR3DECL(int) RTTcpClientClose(RTSOCKET Sock)
{
return rtTcpClose(Sock, "RTTcpClientClose", true /*fTryGracefulShutdown*/);