Commit ceee59a7 authored by Pranjal Raihan's avatar Pranjal Raihan Committed by Facebook GitHub Bot

Migrate AsyncServerSocket to use AtomicNotificationQueue

Reviewed By: andriigrynenko

Differential Revision: D24698220

fbshipit-source-id: aab8c96440d60bb653f0c537af56081819129306
parent dcddc5c0
...@@ -58,14 +58,12 @@ const uint32_t AsyncServerSocket::kDefaultMaxMessagesInQueue; ...@@ -58,14 +58,12 @@ const uint32_t AsyncServerSocket::kDefaultMaxMessagesInQueue;
void AsyncServerSocket::RemoteAcceptor::start( void AsyncServerSocket::RemoteAcceptor::start(
EventBase* eventBase, EventBase* eventBase,
uint32_t maxAtOnce, uint32_t maxAtOnce) {
uint32_t maxInQueue) { queue_.setMaxReadAtOnce(maxAtOnce);
setMaxReadAtOnce(maxAtOnce);
queue_.setMaxQueueSize(maxInQueue);
eventBase->runInEventBaseThread([=]() { eventBase->runInEventBaseThread([=]() {
callback_->acceptStarted(); callback_->acceptStarted();
this->startConsuming(eventBase, &queue_); queue_.startConsuming(eventBase);
}); });
} }
...@@ -78,20 +76,20 @@ void AsyncServerSocket::RemoteAcceptor::stop( ...@@ -78,20 +76,20 @@ void AsyncServerSocket::RemoteAcceptor::stop(
}); });
} }
void AsyncServerSocket::RemoteAcceptor::messageAvailable( void AsyncServerSocket::RemoteAcceptor::Consumer::operator()(
QueueMessage&& msg) noexcept { QueueMessage&& msg) noexcept {
switch (msg.type) { switch (msg.type) {
case MessageType::MSG_NEW_CONN: { case MessageType::MSG_NEW_CONN: {
if (connectionEventCallback_) { if (acceptor_.connectionEventCallback_) {
connectionEventCallback_->onConnectionDequeuedByAcceptorCallback( acceptor_.connectionEventCallback_
msg.fd, msg.address); ->onConnectionDequeuedByAcceptorCallback(msg.fd, msg.address);
} }
callback_->connectionAccepted(msg.fd, msg.address); acceptor_.callback_->connectionAccepted(msg.fd, msg.address);
break; break;
} }
case MessageType::MSG_ERROR: { case MessageType::MSG_ERROR: {
std::runtime_error ex(msg.msg); std::runtime_error ex(msg.msg);
callback_->acceptError(ex); acceptor_.callback_->acceptError(ex);
break; break;
} }
default: { default: {
...@@ -99,7 +97,7 @@ void AsyncServerSocket::RemoteAcceptor::messageAvailable( ...@@ -99,7 +97,7 @@ void AsyncServerSocket::RemoteAcceptor::messageAvailable(
<< int(msg.type); << int(msg.type);
std::runtime_error ex( std::runtime_error ex(
"received invalid accept notification message type"); "received invalid accept notification message type");
callback_->acceptError(ex); acceptor_.callback_->acceptError(ex);
} }
} }
} }
...@@ -597,7 +595,7 @@ void AsyncServerSocket::addAcceptCallback( ...@@ -597,7 +595,7 @@ void AsyncServerSocket::addAcceptCallback(
RemoteAcceptor* acceptor = nullptr; RemoteAcceptor* acceptor = nullptr;
try { try {
acceptor = new RemoteAcceptor(callback, connectionEventCallback_); acceptor = new RemoteAcceptor(callback, connectionEventCallback_);
acceptor->start(eventBase, maxAtOnce, maxNumMsgsInQueue_); acceptor->start(eventBase, maxAtOnce);
} catch (...) { } catch (...) {
callbacks_.pop_back(); callbacks_.pop_back();
delete acceptor; delete acceptor;
...@@ -1017,7 +1015,8 @@ void AsyncServerSocket::dispatchSocket( ...@@ -1017,7 +1015,8 @@ void AsyncServerSocket::dispatchSocket(
// Loop until we find a free queue to write to // Loop until we find a free queue to write to
while (true) { while (true) {
if (info->consumer->getQueue()->tryPutMessageNoThrow(std::move(msg))) { if (info->consumer->getQueue().tryPutMessage(
std::move(msg), maxNumMsgsInQueue_)) {
if (connectionEventCallback_) { if (connectionEventCallback_) {
connectionEventCallback_->onConnectionEnqueuedForAcceptorCallback( connectionEventCallback_->onConnectionEnqueuedForAcceptorCallback(
socket, addr); socket, addr);
...@@ -1077,7 +1076,8 @@ void AsyncServerSocket::dispatchError(const char* msgstr, int errnoValue) { ...@@ -1077,7 +1076,8 @@ void AsyncServerSocket::dispatchError(const char* msgstr, int errnoValue) {
return; return;
} }
if (info->consumer->getQueue()->tryPutMessageNoThrow(std::move(msg))) { if (info->consumer->getQueue().tryPutMessage(
std::move(msg), maxNumMsgsInQueue_)) {
return; return;
} }
// Fall through and try another callback // Fall through and try another callback
......
...@@ -21,10 +21,10 @@ ...@@ -21,10 +21,10 @@
#include <folly/io/ShutdownSocketSet.h> #include <folly/io/ShutdownSocketSet.h>
#include <folly/io/async/AsyncSocketBase.h> #include <folly/io/async/AsyncSocketBase.h>
#include <folly/io/async/AsyncTimeout.h> #include <folly/io/async/AsyncTimeout.h>
#include <folly/io/async/AtomicNotificationQueue.h>
#include <folly/io/async/DelayedDestruction.h> #include <folly/io/async/DelayedDestruction.h>
#include <folly/io/async/EventBase.h> #include <folly/io/async/EventBase.h>
#include <folly/io/async/EventHandler.h> #include <folly/io/async/EventHandler.h>
#include <folly/io/async/NotificationQueue.h>
#include <folly/net/NetOps.h> #include <folly/net/NetOps.h>
#include <folly/net/NetworkSocket.h> #include <folly/net/NetworkSocket.h>
#include <folly/portability/Sockets.h> #include <folly/portability/Sockets.h>
...@@ -550,8 +550,6 @@ class AsyncServerSocket : public DelayedDestruction, public AsyncSocketBase { ...@@ -550,8 +550,6 @@ class AsyncServerSocket : public DelayedDestruction, public AsyncSocketBase {
* Set the maximum number of unprocessed messages in NotificationQueue. * Set the maximum number of unprocessed messages in NotificationQueue.
* No new message will be sent to that NotificationQueue if there are more * No new message will be sent to that NotificationQueue if there are more
* than such number of unprocessed messages in that queue. * than such number of unprocessed messages in that queue.
*
* Only works if called before addAcceptCallback.
*/ */
void setMaxNumMessagesInQueue(uint32_t num) { maxNumMsgsInQueue_ = num; } void setMaxNumMessagesInQueue(uint32_t num) { maxNumMsgsInQueue_ = num; }
...@@ -596,7 +594,7 @@ class AsyncServerSocket : public DelayedDestruction, public AsyncSocketBase { ...@@ -596,7 +594,7 @@ class AsyncServerSocket : public DelayedDestruction, public AsyncSocketBase {
int64_t numMsgs = 0; int64_t numMsgs = 0;
for (const auto& callback : callbacks_) { for (const auto& callback : callbacks_) {
if (callback.consumer) { if (callback.consumer) {
numMsgs += callback.consumer->getQueue()->size(); numMsgs += callback.consumer->getQueue().size();
} }
} }
return numMsgs; return numMsgs;
...@@ -736,28 +734,33 @@ class AsyncServerSocket : public DelayedDestruction, public AsyncSocketBase { ...@@ -736,28 +734,33 @@ class AsyncServerSocket : public DelayedDestruction, public AsyncSocketBase {
* receives notification of new sockets via a NotificationQueue, * receives notification of new sockets via a NotificationQueue,
* and then invokes the AcceptCallback. * and then invokes the AcceptCallback.
*/ */
class RemoteAcceptor : private NotificationQueue<QueueMessage>::Consumer { class RemoteAcceptor {
struct Consumer {
void operator()(QueueMessage&& msg) noexcept;
explicit Consumer(RemoteAcceptor& acceptor) : acceptor_(acceptor) {}
RemoteAcceptor& acceptor_;
};
public: public:
using Queue = AtomicNotificationQueue<QueueMessage, Consumer>;
explicit RemoteAcceptor( explicit RemoteAcceptor(
AcceptCallback* callback, AcceptCallback* callback,
ConnectionEventCallback* connectionEventCallback) ConnectionEventCallback* connectionEventCallback)
: callback_(callback), : callback_(callback),
connectionEventCallback_(connectionEventCallback) {} connectionEventCallback_(connectionEventCallback),
queue_(Consumer(*this)) {}
~RemoteAcceptor() override = default; void start(EventBase* eventBase, uint32_t maxAtOnce);
void start(EventBase* eventBase, uint32_t maxAtOnce, uint32_t maxInQueue);
void stop(EventBase* eventBase, AcceptCallback* callback); void stop(EventBase* eventBase, AcceptCallback* callback);
void messageAvailable(QueueMessage&& msg) noexcept override; Queue& getQueue() { return queue_; }
NotificationQueue<QueueMessage>* getQueue() { return &queue_; }
private: private:
AcceptCallback* callback_; AcceptCallback* callback_;
ConnectionEventCallback* connectionEventCallback_; ConnectionEventCallback* connectionEventCallback_;
Queue queue_;
NotificationQueue<QueueMessage> queue_;
}; };
/** /**
......
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