Commit 6612bf09 authored by Fuat Geleri's avatar Fuat Geleri Committed by Facebook Github Bot

Enable EventBase switching for AsyncSocket even if it has registered events

Summary:
AsyncSocket will return isDetachable() -> false if there is a read callback set.
So,
 - ignore event registration status
 - unregister the events when detaching and
 - register them back when attaching again.

Reviewed By: afrind, eduardo-elizondo

Differential Revision: D6331787

fbshipit-source-id: fca4e6101f2d5666edbafa09116aa50f34cb084d
parent 277bd447
......@@ -1434,6 +1434,9 @@ void AsyncSocket::attachEventBase(EventBase* eventBase) {
eventBase_ = eventBase;
ioHandler_.attachEventBase(eventBase);
updateEventRegistration();
writeTimeout_.attachEventBase(eventBase);
if (evbChangeCb_) {
evbChangeCb_->evbAttached(this);
......@@ -1448,6 +1451,9 @@ void AsyncSocket::detachEventBase() {
eventBase_->dcheckIsInEventBaseThread();
eventBase_ = nullptr;
ioHandler_.unregisterHandler();
ioHandler_.detachEventBase();
writeTimeout_.detachEventBase();
if (evbChangeCb_) {
......@@ -1459,7 +1465,7 @@ bool AsyncSocket::isDetachable() const {
DCHECK(eventBase_ != nullptr);
eventBase_->dcheckIsInEventBaseThread();
return !ioHandler_.isHandlerRegistered() && !writeTimeout_.isScheduled();
return !writeTimeout_.isScheduled();
}
void AsyncSocket::cacheAddresses() {
......
......@@ -2857,6 +2857,39 @@ TEST(AsyncSocketTest, EvbCallbacks) {
socket->attachEventBase(&evb);
}
TEST(AsyncSocketTest, TestEvbDetachWtRegisteredIOHandlers) {
// Start listening on a local port
TestServer server;
// Connect using a AsyncSocket
EventBase evb;
std::shared_ptr<AsyncSocket> socket = AsyncSocket::newSocket(&evb);
ConnCallback cb;
socket->connect(&cb, server.getAddress(), 30);
evb.loop();
ASSERT_EQ(cb.state, STATE_SUCCEEDED);
EXPECT_LE(0, socket->getConnectTime().count());
EXPECT_EQ(socket->getConnectTimeout(), std::chrono::milliseconds(30));
// After the ioHandlers are registered, still should be able to detach/attach
ReadCallback rcb;
socket->setReadCB(&rcb);
auto cbEvbChg = std::make_unique<MockEvbChangeCallback>();
InSequence seq;
EXPECT_CALL(*cbEvbChg, evbDetached(socket.get())).Times(1);
EXPECT_CALL(*cbEvbChg, evbAttached(socket.get())).Times(1);
socket->setEvbChangedCallback(std::move(cbEvbChg));
EXPECT_TRUE(socket->isDetachable());
socket->detachEventBase();
socket->attachEventBase(&evb);
socket->close();
}
#ifdef FOLLY_HAVE_MSG_ERRQUEUE
/* copied from include/uapi/linux/net_tstamp.h */
/* SO_TIMESTAMPING gets an integer bit field comprised of these values */
......
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