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) { ...@@ -1434,6 +1434,9 @@ void AsyncSocket::attachEventBase(EventBase* eventBase) {
eventBase_ = eventBase; eventBase_ = eventBase;
ioHandler_.attachEventBase(eventBase); ioHandler_.attachEventBase(eventBase);
updateEventRegistration();
writeTimeout_.attachEventBase(eventBase); writeTimeout_.attachEventBase(eventBase);
if (evbChangeCb_) { if (evbChangeCb_) {
evbChangeCb_->evbAttached(this); evbChangeCb_->evbAttached(this);
...@@ -1448,6 +1451,9 @@ void AsyncSocket::detachEventBase() { ...@@ -1448,6 +1451,9 @@ void AsyncSocket::detachEventBase() {
eventBase_->dcheckIsInEventBaseThread(); eventBase_->dcheckIsInEventBaseThread();
eventBase_ = nullptr; eventBase_ = nullptr;
ioHandler_.unregisterHandler();
ioHandler_.detachEventBase(); ioHandler_.detachEventBase();
writeTimeout_.detachEventBase(); writeTimeout_.detachEventBase();
if (evbChangeCb_) { if (evbChangeCb_) {
...@@ -1459,7 +1465,7 @@ bool AsyncSocket::isDetachable() const { ...@@ -1459,7 +1465,7 @@ bool AsyncSocket::isDetachable() const {
DCHECK(eventBase_ != nullptr); DCHECK(eventBase_ != nullptr);
eventBase_->dcheckIsInEventBaseThread(); eventBase_->dcheckIsInEventBaseThread();
return !ioHandler_.isHandlerRegistered() && !writeTimeout_.isScheduled(); return !writeTimeout_.isScheduled();
} }
void AsyncSocket::cacheAddresses() { void AsyncSocket::cacheAddresses() {
......
...@@ -2857,6 +2857,39 @@ TEST(AsyncSocketTest, EvbCallbacks) { ...@@ -2857,6 +2857,39 @@ TEST(AsyncSocketTest, EvbCallbacks) {
socket->attachEventBase(&evb); 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 #ifdef FOLLY_HAVE_MSG_ERRQUEUE
/* copied from include/uapi/linux/net_tstamp.h */ /* copied from include/uapi/linux/net_tstamp.h */
/* SO_TIMESTAMPING gets an integer bit field comprised of these values */ /* 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