summaryrefslogtreecommitdiffstats
path: root/src/OSSupport
diff options
context:
space:
mode:
Diffstat (limited to 'src/OSSupport')
-rw-r--r--src/OSSupport/Network.h18
-rw-r--r--src/OSSupport/ServerHandleImpl.cpp2
-rw-r--r--src/OSSupport/TCPLinkImpl.cpp26
-rw-r--r--src/OSSupport/TCPLinkImpl.h11
4 files changed, 42 insertions, 15 deletions
diff --git a/src/OSSupport/Network.h b/src/OSSupport/Network.h
index b9ca377cb..85c7c5dcb 100644
--- a/src/OSSupport/Network.h
+++ b/src/OSSupport/Network.h
@@ -13,6 +13,14 @@
+// fwd:
+class cTCPLink;
+typedef SharedPtr<cTCPLink> cTCPLinkPtr;
+
+
+
+
+
/** Interface that provides the methods available on a single TCP connection. */
class cTCPLink
{
@@ -25,16 +33,20 @@ public:
// Force a virtual destructor for all descendants:
virtual ~cCallbacks() {}
+ /** Called when the cTCPLink for the connection is created.
+ The callback may store the cTCPLink instance for later use, but it should remove it in OnError(), OnRemoteClosed() or right after Close(). */
+ virtual void OnLinkCreated(cTCPLinkPtr a_Link) = 0;
+
/** Called when there's data incoming from the remote peer. */
- virtual void OnReceivedData(cTCPLink & a_Link, const char * a_Data, size_t a_Length) = 0;
+ virtual void OnReceivedData(const char * a_Data, size_t a_Length) = 0;
/** Called when the remote end closes the connection.
The link is still available for connection information query (IP / port).
Sending data on the link is not an error, but the data won't be delivered. */
- virtual void OnRemoteClosed(cTCPLink & a_Link) = 0;
+ virtual void OnRemoteClosed(void) = 0;
/** Called when an error is detected on the connection. */
- virtual void OnError(cTCPLink & a_Link, int a_ErrorCode, const AString & a_ErrorMsg) = 0;
+ virtual void OnError(int a_ErrorCode, const AString & a_ErrorMsg) = 0;
};
typedef SharedPtr<cCallbacks> cCallbacksPtr;
diff --git a/src/OSSupport/ServerHandleImpl.cpp b/src/OSSupport/ServerHandleImpl.cpp
index 82cbecef2..026c0fdc1 100644
--- a/src/OSSupport/ServerHandleImpl.cpp
+++ b/src/OSSupport/ServerHandleImpl.cpp
@@ -283,6 +283,8 @@ void cServerHandleImpl::Callback(evconnlistener * a_Listener, evutil_socket_t a_
cCSLock Lock(Self->m_CS);
Self->m_Connections.push_back(Link);
} // Lock(m_CS)
+ LinkCallbacks->OnLinkCreated(Link);
+ Link->Enable();
// Call the OnAccepted callback:
Self->m_ListenCallbacks->OnAccepted(*Link);
diff --git a/src/OSSupport/TCPLinkImpl.cpp b/src/OSSupport/TCPLinkImpl.cpp
index 6f937646f..5d31da22e 100644
--- a/src/OSSupport/TCPLinkImpl.cpp
+++ b/src/OSSupport/TCPLinkImpl.cpp
@@ -20,9 +20,6 @@ cTCPLinkImpl::cTCPLinkImpl(cTCPLink::cCallbacksPtr a_LinkCallbacks):
m_BufferEvent(bufferevent_socket_new(cNetworkSingleton::Get().GetEventBase(), -1, BEV_OPT_CLOSE_ON_FREE)),
m_Server(nullptr)
{
- // Create the LibEvent handle, but don't assign a socket to it yet (will be assigned within Connect() method):
- bufferevent_setcb(m_BufferEvent, ReadCallback, nullptr, EventCallback, this);
- bufferevent_enable(m_BufferEvent, EV_READ | EV_WRITE);
}
@@ -37,10 +34,6 @@ cTCPLinkImpl::cTCPLinkImpl(evutil_socket_t a_Socket, cTCPLink::cCallbacksPtr a_L
// Update the endpoint addresses:
UpdateLocalAddress();
UpdateAddress(a_Address, a_AddrLen, m_RemoteIP, m_RemotePort);
-
- // Create the LibEvent handle:
- bufferevent_setcb(m_BufferEvent, ReadCallback, nullptr, EventCallback, this);
- bufferevent_enable(m_BufferEvent, EV_READ | EV_WRITE);
}
@@ -65,6 +58,8 @@ cTCPLinkImplPtr cTCPLinkImpl::Connect(const AString & a_Host, UInt16 a_Port, cTC
cTCPLinkImplPtr res{new cTCPLinkImpl(a_LinkCallbacks)}; // Cannot use std::make_shared here, constructor is not accessible
res->m_ConnectCallbacks = a_ConnectCallbacks;
cNetworkSingleton::Get().AddLink(res);
+ res->m_Callbacks->OnLinkCreated(res);
+ res->Enable();
// If a_Host is an IP address, schedule a connection immediately:
sockaddr_storage sa;
@@ -107,6 +102,17 @@ cTCPLinkImplPtr cTCPLinkImpl::Connect(const AString & a_Host, UInt16 a_Port, cTC
+void cTCPLinkImpl::Enable(void)
+{
+ // Set the LibEvent callbacks and enable processing:
+ bufferevent_setcb(m_BufferEvent, ReadCallback, nullptr, EventCallback, this);
+ bufferevent_enable(m_BufferEvent, EV_READ | EV_WRITE);
+}
+
+
+
+
+
bool cTCPLinkImpl::Send(const void * a_Data, size_t a_Length)
{
return (bufferevent_write(m_BufferEvent, a_Data, a_Length) == 0);
@@ -160,7 +166,7 @@ void cTCPLinkImpl::ReadCallback(bufferevent * a_BufferEvent, void * a_Self)
size_t length;
while ((length = bufferevent_read(a_BufferEvent, data, sizeof(data))) > 0)
{
- Self->m_Callbacks->OnReceivedData(*Self, data, length);
+ Self->m_Callbacks->OnReceivedData(data, length);
}
}
@@ -189,7 +195,7 @@ void cTCPLinkImpl::EventCallback(bufferevent * a_BufferEvent, short a_What, void
}
else
{
- Self->m_Callbacks->OnError(*Self, err, evutil_socket_error_to_string(err));
+ Self->m_Callbacks->OnError(err, evutil_socket_error_to_string(err));
if (Self->m_Server == nullptr)
{
cNetworkSingleton::Get().RemoveLink(Self);
@@ -219,7 +225,7 @@ void cTCPLinkImpl::EventCallback(bufferevent * a_BufferEvent, short a_What, void
// If the connection has been closed, call the link callback and remove the connection:
if (a_What & BEV_EVENT_EOF)
{
- Self->m_Callbacks->OnRemoteClosed(*Self);
+ Self->m_Callbacks->OnRemoteClosed();
if (Self->m_Server != nullptr)
{
Self->m_Server->RemoveLink(Self);
diff --git a/src/OSSupport/TCPLinkImpl.h b/src/OSSupport/TCPLinkImpl.h
index edd295fe2..66347afe0 100644
--- a/src/OSSupport/TCPLinkImpl.h
+++ b/src/OSSupport/TCPLinkImpl.h
@@ -37,7 +37,8 @@ class cTCPLinkImpl:
public:
/** Creates a new link based on the given socket.
Used for connections accepted in a server using cNetwork::Listen().
- a_Address and a_AddrLen describe the remote peer that has connected. */
+ a_Address and a_AddrLen describe the remote peer that has connected.
+ The link is created disabled, you need to call Enable() to start the regular communication. */
cTCPLinkImpl(evutil_socket_t a_Socket, cCallbacksPtr a_LinkCallbacks, cServerHandleImpl * a_Server, const sockaddr * a_Address, socklen_t a_AddrLen);
/** Destroys the LibEvent handle representing the link. */
@@ -48,6 +49,11 @@ public:
Returns a link that has the connection request queued, or NULL for failure. */
static cTCPLinkImplPtr Connect(const AString & a_Host, UInt16 a_Port, cTCPLink::cCallbacksPtr a_LinkCallbacks, cNetwork::cConnectCallbacksPtr a_ConnectCallbacks);
+ /** Enables communication over the link.
+ Links are created with communication disabled, so that creation callbacks can be called first.
+ This function then enables the regular communication to be reported. */
+ void Enable(void);
+
// cTCPLink overrides:
virtual bool Send(const void * a_Data, size_t a_Length) override;
virtual AString GetLocalIP(void) const override { return m_LocalIP; }
@@ -85,7 +91,8 @@ protected:
/** Creates a new link to be queued to connect to a specified host:port.
Used for outgoing connections created using cNetwork::Connect().
- To be used only by the Connect() factory function. */
+ To be used only by the Connect() factory function.
+ The link is created disabled, you need to call Enable() to start the regular communication. */
cTCPLinkImpl(const cCallbacksPtr a_LinkCallbacks);
/** Callback that LibEvent calls when there's data available from the remote peer. */