Commit 104d728c authored by Brandon Schlinker's avatar Brandon Schlinker Committed by Facebook GitHub Bot

Construct from existing raw pointer

Summary:
This diff adds a constructor that takes an `AsyncSocket*`, so that lifecycle observers are informed via `move` when a socket is transformed.

If one `AsyncSocket` is constructed from another using the `AsyncSocket(AsyncSocket* oldAsyncSocket)` constructor, then `move(oldSocket, newSocket)` will be triggered for attached observers, allowing the observers to detach from the old socket and attach to the new socket. However, we currently transform between `AsyncSocket` by detaching the fd and event base, and passing them to the new constructor:

```
# from FizzAcceptorHandshakeHelper.cpp
auto evb = transport_->getEventBase();
auto fd = transport_->getUnderlyingTransport<folly::AsyncSocket>()
                ->detachNetworkSocket()
                .toFd();
transport_.reset();
sslSocket_ = createSSLSocket(sslContext_, evb, fd);
```

When this happens, any `AsyncSocket::LifecycleObserver` that were attached on accept to become separated from the fd/socket that they're attempting to follow. With this change, we can do the following instead (next diff):

```
 sslSocket_ = createSSLSocket(
      sslContext_, transport_->getUnderlyingTransport<folly::AsyncSocket>());
transport_.reset();
```

Because `createSSLSocket` uses the `AsyncSocket*` constructor, the `move` observer event will be triggered.

Differential Revision: D21614835

fbshipit-source-id: 6c995f879fe41935850247a28ff8af2b33349445
parent 5e4b2f87
......@@ -253,10 +253,10 @@ AsyncSSLSocket::AsyncSSLSocket(
AsyncSSLSocket::AsyncSSLSocket(
shared_ptr<SSLContext> ctx,
AsyncSocket::UniquePtr oldAsyncSocket,
AsyncSocket* oldAsyncSocket,
bool server,
bool deferSecurityNegotiation)
: AsyncSocket(std::move(oldAsyncSocket)),
: AsyncSocket(oldAsyncSocket),
server_(server),
ctx_(std::move(ctx)),
handshakeTimeout_(this, AsyncSocket::getEventBase()),
......@@ -272,6 +272,17 @@ AsyncSSLSocket::AsyncSSLSocket(
}
}
AsyncSSLSocket::AsyncSSLSocket(
shared_ptr<SSLContext> ctx,
AsyncSocket::UniquePtr oldAsyncSocket,
bool server,
bool deferSecurityNegotiation)
: AsyncSSLSocket(
ctx,
oldAsyncSocket.get(),
server,
deferSecurityNegotiation) {}
#if FOLLY_OPENSSL_HAS_SNI
/**
* Create a client AsyncSSLSocket and allow tlsext_hostname
......
......@@ -228,6 +228,16 @@ class AsyncSSLSocket : public AsyncSocket {
bool server = true,
bool deferSecurityNegotiation = false);
/**
* Create a server/client AsyncSSLSocket from an already connected
* AsyncSocket.
*/
AsyncSSLSocket(
std::shared_ptr<folly::SSLContext> ctx,
AsyncSocket* oldAsyncSocket,
bool server = true,
bool deferSecurityNegotiation = false);
/**
* Create a server/client AsyncSSLSocket from an already connected
* AsyncSocket.
......
......@@ -344,7 +344,7 @@ AsyncSocket::AsyncSocket(
state_ = StateEnum::ESTABLISHED;
}
AsyncSocket::AsyncSocket(AsyncSocket::UniquePtr oldAsyncSocket)
AsyncSocket::AsyncSocket(AsyncSocket* oldAsyncSocket)
: AsyncSocket(
oldAsyncSocket->getEventBase(),
oldAsyncSocket->detachNetworkSocket(),
......@@ -357,11 +357,14 @@ AsyncSocket::AsyncSocket(AsyncSocket::UniquePtr oldAsyncSocket)
for (const auto& cb : oldAsyncSocket->lifecycleObservers_) {
// only available for observers derived from AsyncSocket::LifecycleObserver
if (auto dCb = dynamic_cast<AsyncSocket::LifecycleObserver*>(cb)) {
dCb->move(oldAsyncSocket.get(), this);
dCb->move(oldAsyncSocket, this);
}
}
}
AsyncSocket::AsyncSocket(AsyncSocket::UniquePtr oldAsyncSocket)
: AsyncSocket(oldAsyncSocket.get()) {}
// init() method, since constructor forwarding isn't supported in most
// compilers yet.
void AsyncSocket::init() {
......
......@@ -288,6 +288,15 @@ class AsyncSocket : public AsyncTransport {
*/
explicit AsyncSocket(AsyncSocket::UniquePtr);
/**
* Create an AsyncSocket from a different, already connected AsyncSocket.
*
* Similar to AsyncSocket(evb, fd) when fd was previously owned by an
* AsyncSocket. Caller must call destroy on old AsyncSocket unless it is
* in a smart pointer with appropriate destructor.
*/
explicit AsyncSocket(AsyncSocket*);
/**
* Helper function to create an AsyncSocket..
*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment