Commit 653f9938 authored by Rob Sherwood's avatar Rob Sherwood Committed by Facebook GitHub Bot

Add ConstructorCallback to AyncSocket

Summary:
Use the new ConstructorCallback class to allow exterior functions/classes
to get a callback for each new AsyncSocket()

Implications:
This adds an optional and an atomic int to the size of each AsyncSocket so
there is a very small increase in mem usage even if this is unused (which will
be most code, at least initially).

There is also a very small amount of additional CPU on constructing an
AsyncSocket: checking the std::option to see if it's non-nullopt.

Reviewed By: bschlinker

Differential Revision: D27516379

fbshipit-source-id: 56f4411afcd404dcf0092cce562230e5c0dcdf17
parent 44739203
......@@ -22,6 +22,7 @@
#include <map>
#include <memory>
#include <folly/ConstructorCallback.h>
#include <folly/Optional.h>
#include <folly/SocketAddress.h>
#include <folly/detail/SocketFastOpen.h>
......@@ -1598,6 +1599,12 @@ class AsyncSocket : public AsyncTransport {
bool closeOnFailedWrite_{true};
netops::DispatcherContainer netops_;
// allow other functions to register for callbacks when
// new AsyncSocket()'s are created
// must be LAST member defined to ensure other members are initialized
// before access; see ConstructorCallback.h for details
ConstructorCallback<AsyncSocket> constructorCallback_{this};
};
} // namespace folly
......@@ -5251,6 +5251,31 @@ TEST_P(AsyncSocketByteEventHelperOffsetTest, CheckCalculatedOffset) {
#endif // FOLLY_HAVE_SO_TIMESTAMPING
TEST(AsyncSocket, LifecycleCtorCallback) {
EventBase evb;
// create socket and verify that w/o a ctor callback, nothing happens
auto socket1 = AsyncSocket::UniquePtr(new AsyncSocket(&evb));
EXPECT_EQ(socket1->getLifecycleObservers().size(), 0);
// Then register a ctor callback that registers a mock lifecycle observer
// NB: use nicemock instead of strict b/c the actual lifecycle testing
// is done below and this simplifies the test
auto lifecycleCB =
std::make_shared<NiceMock<MockAsyncSocketLifecycleObserver>>();
auto lifecycleRawPtr = lifecycleCB.get();
// verify the first part of the lifecycle was processed
ConstructorCallback<AsyncSocket>::addNewConstructorCallback(
[lifecycleRawPtr](AsyncSocket* s) {
s->addLifecycleObserver(lifecycleRawPtr);
});
auto socket2 = AsyncSocket::UniquePtr(new AsyncSocket(&evb));
EXPECT_EQ(socket2->getLifecycleObservers().size(), 1);
EXPECT_THAT(
socket2->getLifecycleObservers(),
UnorderedElementsAre(lifecycleCB.get()));
Mock::VerifyAndClearExpectations(lifecycleCB.get());
}
TEST(AsyncSocket, LifecycleObserverDetachAndAttachEvb) {
auto cb = std::make_unique<StrictMock<MockAsyncSocketLifecycleObserver>>();
EventBase evb;
......
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