CodeMod apache::thrift::transport::TSocketAddress to folly::SocketAddress.
[folly.git] / folly / io / async / AsyncServerSocket.h
1 /*
2  * Copyright 2015 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #pragma once
18
19 #include <folly/io/async/DelayedDestruction.h>
20 #include <folly/io/async/EventHandler.h>
21 #include <folly/io/async/EventBase.h>
22 #include <folly/io/async/NotificationQueue.h>
23 #include <folly/io/async/AsyncTimeout.h>
24 #include <folly/io/async/AsyncSocketBase.h>
25 #include <folly/io/ShutdownSocketSet.h>
26 #include <folly/SocketAddress.h>
27 #include <memory>
28 #include <exception>
29 #include <vector>
30 #include <limits.h>
31 #include <stddef.h>
32 #include <sys/socket.h>
33
34
35 // Due to the way kernel headers are included, this may or may not be defined.
36 // Number pulled from 3.10 kernel headers.
37 #ifndef SO_REUSEPORT
38 #define SO_REUSEPORT 15
39 #endif
40
41 namespace folly {
42
43 /**
44  * A listening socket that asynchronously informs a callback whenever a new
45  * connection has been accepted.
46  *
47  * Unlike most async interfaces that always invoke their callback in the same
48  * EventBase thread, AsyncServerSocket is unusual in that it can distribute
49  * the callbacks across multiple EventBase threads.
50  *
51  * This supports a common use case for network servers to distribute incoming
52  * connections across a number of EventBase threads.  (Servers typically run
53  * with one EventBase thread per CPU.)
54  *
55  * Despite being able to invoke callbacks in multiple EventBase threads,
56  * AsyncServerSocket still has one "primary" EventBase.  Operations that
57  * modify the AsyncServerSocket state may only be performed from the primary
58  * EventBase thread.
59  */
60 class AsyncServerSocket : public DelayedDestruction
61                         , public AsyncSocketBase {
62  public:
63   typedef std::unique_ptr<AsyncServerSocket, Destructor> UniquePtr;
64   // Disallow copy, move, and default construction.
65   AsyncServerSocket(AsyncServerSocket&&) = delete;
66
67   class AcceptCallback {
68    public:
69     virtual ~AcceptCallback() = default;
70
71     /**
72      * connectionAccepted() is called whenever a new client connection is
73      * received.
74      *
75      * The AcceptCallback will remain installed after connectionAccepted()
76      * returns.
77      *
78      * @param fd          The newly accepted client socket.  The AcceptCallback
79      *                    assumes ownership of this socket, and is responsible
80      *                    for closing it when done.  The newly accepted file
81      *                    descriptor will have already been put into
82      *                    non-blocking mode.
83      * @param clientAddr  A reference to a SocketAddress struct containing the
84      *                    client's address.  This struct is only guaranteed to
85      *                    remain valid until connectionAccepted() returns.
86      */
87     virtual void connectionAccepted(int fd,
88                                     const SocketAddress& clientAddr)
89       noexcept = 0;
90
91     /**
92      * acceptError() is called if an error occurs while accepting.
93      *
94      * The AcceptCallback will remain installed even after an accept error,
95      * as the errors are typically somewhat transient, such as being out of
96      * file descriptors.  The server socket must be explicitly stopped if you
97      * wish to stop accepting after an error.
98      *
99      * @param ex  An exception representing the error.
100      */
101     virtual void acceptError(const std::exception& ex) noexcept = 0;
102
103     /**
104      * acceptStarted() will be called in the callback's EventBase thread
105      * after this callback has been added to the AsyncServerSocket.
106      *
107      * acceptStarted() will be called before any calls to connectionAccepted()
108      * or acceptError() are made on this callback.
109      *
110      * acceptStarted() makes it easier for callbacks to perform initialization
111      * inside the callback thread.  (The call to addAcceptCallback() must
112      * always be made from the AsyncServerSocket's primary EventBase thread.
113      * acceptStarted() provides a hook that will always be invoked in the
114      * callback's thread.)
115      *
116      * Note that the call to acceptStarted() is made once the callback is
117      * added, regardless of whether or not the AsyncServerSocket is actually
118      * accepting at the moment.  acceptStarted() will be called even if the
119      * AsyncServerSocket is paused when the callback is added (including if
120      * the initial call to startAccepting() on the AsyncServerSocket has not
121      * been made yet).
122      */
123     virtual void acceptStarted() noexcept {}
124
125     /**
126      * acceptStopped() will be called when this AcceptCallback is removed from
127      * the AsyncServerSocket, or when the AsyncServerSocket is destroyed,
128      * whichever occurs first.
129      *
130      * No more calls to connectionAccepted() or acceptError() will be made
131      * after acceptStopped() is invoked.
132      */
133     virtual void acceptStopped() noexcept {}
134   };
135
136   static const uint32_t kDefaultMaxAcceptAtOnce = 30;
137   static const uint32_t kDefaultCallbackAcceptAtOnce = 5;
138   static const uint32_t kDefaultMaxMessagesInQueue = 0;
139   /**
140    * Create a new AsyncServerSocket with the specified EventBase.
141    *
142    * @param eventBase  The EventBase to use for driving the asynchronous I/O.
143    *                   If this parameter is nullptr, attachEventBase() must be
144    *                   called before this socket can begin accepting
145    *                   connections.
146    */
147   explicit AsyncServerSocket(EventBase* eventBase = nullptr);
148
149   /**
150    * Helper function to create a shared_ptr<AsyncServerSocket>.
151    *
152    * This passes in the correct destructor object, since AsyncServerSocket's
153    * destructor is protected and cannot be invoked directly.
154    */
155   static std::shared_ptr<AsyncServerSocket>
156   newSocket(EventBase* evb = nullptr) {
157     return std::shared_ptr<AsyncServerSocket>(new AsyncServerSocket(evb),
158                                                  Destructor());
159   }
160
161   void setShutdownSocketSet(ShutdownSocketSet* newSS);
162
163   /**
164    * Destroy the socket.
165    *
166    * AsyncServerSocket::destroy() must be called to destroy the socket.
167    * The normal destructor is private, and should not be invoked directly.
168    * This prevents callers from deleting a AsyncServerSocket while it is
169    * invoking a callback.
170    *
171    * destroy() must be invoked from the socket's primary EventBase thread.
172    *
173    * If there are AcceptCallbacks still installed when destroy() is called,
174    * acceptStopped() will be called on these callbacks to notify them that
175    * accepting has stopped.  Accept callbacks being driven by other EventBase
176    * threads may continue to receive new accept callbacks for a brief period of
177    * time after destroy() returns.  They will not receive any more callback
178    * invocations once acceptStopped() is invoked.
179    */
180   virtual void destroy();
181
182   /**
183    * Attach this AsyncServerSocket to its primary EventBase.
184    *
185    * This may only be called if the AsyncServerSocket is not already attached
186    * to a EventBase.  The AsyncServerSocket must be attached to a EventBase
187    * before it can begin accepting connections.
188    */
189   void attachEventBase(EventBase *eventBase);
190
191   /**
192    * Detach the AsyncServerSocket from its primary EventBase.
193    *
194    * detachEventBase() may only be called if the AsyncServerSocket is not
195    * currently accepting connections.
196    */
197   void detachEventBase();
198
199   /**
200    * Get the EventBase used by this socket.
201    */
202   EventBase* getEventBase() const {
203     return eventBase_;
204   }
205
206   /**
207    * Create a AsyncServerSocket from an existing socket file descriptor.
208    *
209    * useExistingSocket() will cause the AsyncServerSocket to take ownership of
210    * the specified file descriptor, and use it to listen for new connections.
211    * The AsyncServerSocket will close the file descriptor when it is
212    * destroyed.
213    *
214    * useExistingSocket() must be called before bind() or listen().
215    *
216    * The supplied file descriptor will automatically be put into non-blocking
217    * mode.  The caller may have already directly called bind() and possibly
218    * listen on the file descriptor.  If so the caller should skip calling the
219    * corresponding AsyncServerSocket::bind() and listen() methods.
220    *
221    * On error a TTransportException will be thrown and the caller will retain
222    * ownership of the file descriptor.
223    */
224   void useExistingSocket(int fd);
225   void useExistingSockets(const std::vector<int>& fds);
226
227   /**
228    * Return the underlying file descriptor
229    */
230   std::vector<int> getSockets() const {
231     std::vector<int> sockets;
232     for (auto& handler : sockets_) {
233       sockets.push_back(handler.socket_);
234     }
235     return sockets;
236   }
237
238   /**
239    * Backwards compatible getSocket, warns if > 1 socket
240    */
241   int getSocket() const {
242     if (sockets_.size() > 1) {
243       VLOG(2) << "Warning: getSocket can return multiple fds, " <<
244         "but getSockets was not called, so only returning the first";
245     }
246     if (sockets_.size() == 0) {
247       return -1;
248     } else {
249       return sockets_[0].socket_;
250     }
251   }
252
253   /**
254    * Bind to the specified address.
255    *
256    * This must be called from the primary EventBase thread.
257    *
258    * Throws TTransportException on error.
259    */
260   virtual void bind(const SocketAddress& address);
261
262   /**
263    * Bind to the specified port for the specified addresses.
264    *
265    * This must be called from the primary EventBase thread.
266    *
267    * Throws TTransportException on error.
268    */
269   virtual void bind(
270       const std::vector<IPAddress>& ipAddresses,
271       uint16_t port);
272
273   /**
274    * Bind to the specified port.
275    *
276    * This must be called from the primary EventBase thread.
277    *
278    * Throws TTransportException on error.
279    */
280   virtual void bind(uint16_t port);
281
282   /**
283    * Get the local address to which the socket is bound.
284    *
285    * Throws TTransportException on error.
286    */
287   void getAddress(SocketAddress* addressReturn) const;
288
289   /**
290    * Get all the local addresses to which the socket is bound.
291    *
292    * Throws TTransportException on error.
293    */
294   std::vector<SocketAddress> getAddresses() const;
295
296   /**
297    * Begin listening for connections.
298    *
299    * This calls ::listen() with the specified backlog.
300    *
301    * Once listen() is invoked the socket will actually be open so that remote
302    * clients may establish connections.  (Clients that attempt to connect
303    * before listen() is called will receive a connection refused error.)
304    *
305    * At least one callback must be set and startAccepting() must be called to
306    * actually begin notifying the accept callbacks of newly accepted
307    * connections.  The backlog parameter controls how many connections the
308    * kernel will accept and buffer internally while the accept callbacks are
309    * paused (or if accepting is enabled but the callbacks cannot keep up).
310    *
311    * bind() must be called before calling listen().
312    * listen() must be called from the primary EventBase thread.
313    *
314    * Throws TTransportException on error.
315    */
316   virtual void listen(int backlog);
317
318   /**
319    * Add an AcceptCallback.
320    *
321    * When a new socket is accepted, one of the AcceptCallbacks will be invoked
322    * with the new socket.  The AcceptCallbacks are invoked in a round-robin
323    * fashion.  This allows the accepted sockets to distributed among a pool of
324    * threads, each running its own EventBase object.  This is a common model,
325    * since most asynchronous-style servers typically run one EventBase thread
326    * per CPU.
327    *
328    * The EventBase object associated with each AcceptCallback must be running
329    * its loop.  If the EventBase loop is not running, sockets will still be
330    * scheduled for the callback, but the callback cannot actually get invoked
331    * until the loop runs.
332    *
333    * This method must be invoked from the AsyncServerSocket's primary
334    * EventBase thread.
335    *
336    * Note that startAccepting() must be called on the AsyncServerSocket to
337    * cause it to actually start accepting sockets once callbacks have been
338    * installed.
339    *
340    * @param callback   The callback to invoke.
341    * @param eventBase  The EventBase to use to invoke the callback.  This
342    *     parameter may be nullptr, in which case the callback will be invoked in
343    *     the AsyncServerSocket's primary EventBase.
344    * @param maxAtOnce  The maximum number of connections to accept in this
345    *                   callback on a single iteration of the event base loop.
346    *                   This only takes effect when eventBase is non-nullptr.
347    *                   When using a nullptr eventBase for the callback, the
348    *                   setMaxAcceptAtOnce() method controls how many
349    *                   connections the main event base will accept at once.
350    */
351   virtual void addAcceptCallback(
352     AcceptCallback *callback,
353     EventBase *eventBase,
354     uint32_t maxAtOnce = kDefaultCallbackAcceptAtOnce);
355
356   /**
357    * Remove an AcceptCallback.
358    *
359    * This allows a single AcceptCallback to be removed from the round-robin
360    * pool.
361    *
362    * This method must be invoked from the AsyncServerSocket's primary
363    * EventBase thread.  Use EventBase::runInEventBaseThread() to schedule the
364    * operation in the correct EventBase if your code is not in the server
365    * socket's primary EventBase.
366    *
367    * Given that the accept callback is being driven by a different EventBase,
368    * the AcceptCallback may continue to be invoked for a short period of time
369    * after removeAcceptCallback() returns in this thread.  Once the other
370    * EventBase thread receives the notification to stop, it will call
371    * acceptStopped() on the callback to inform it that it is fully stopped and
372    * will not receive any new sockets.
373    *
374    * If the last accept callback is removed while the socket is accepting,
375    * the socket will implicitly pause accepting.  If a callback is later added,
376    * it will resume accepting immediately, without requiring startAccepting()
377    * to be invoked.
378    *
379    * @param callback   The callback to uninstall.
380    * @param eventBase  The EventBase associated with this callback.  This must
381    *     be the same EventBase that was used when the callback was installed
382    *     with addAcceptCallback().
383    */
384   void removeAcceptCallback(AcceptCallback *callback, EventBase *eventBase);
385
386   /**
387    * Begin accepting connctions on this socket.
388    *
389    * bind() and listen() must be called before calling startAccepting().
390    *
391    * When a AsyncServerSocket is initially created, it will not begin
392    * accepting connections until at least one callback has been added and
393    * startAccepting() has been called.  startAccepting() can also be used to
394    * resume accepting connections after a call to pauseAccepting().
395    *
396    * If startAccepting() is called when there are no accept callbacks
397    * installed, the socket will not actually begin accepting until an accept
398    * callback is added.
399    *
400    * This method may only be called from the primary EventBase thread.
401    */
402   virtual void startAccepting();
403
404   /**
405    * Pause accepting connections.
406    *
407    * startAccepting() may be called to resume accepting.
408    *
409    * This method may only be called from the primary EventBase thread.
410    * If there are AcceptCallbacks being driven by other EventBase threads they
411    * may continue to receive callbacks for a short period of time after
412    * pauseAccepting() returns.
413    *
414    * Unlike removeAcceptCallback() or destroy(), acceptStopped() will not be
415    * called on the AcceptCallback objects simply due to a temporary pause.  If
416    * the server socket is later destroyed while paused, acceptStopped() will be
417    * called all of the installed AcceptCallbacks.
418    */
419   void pauseAccepting();
420
421   /**
422    * Shutdown the listen socket and notify all callbacks that accept has
423    * stopped, but don't close the socket.  This invokes shutdown(2) with the
424    * supplied argument.  Passing -1 will close the socket now.  Otherwise, the
425    * close will be delayed until this object is destroyed.
426    *
427    * Only use this if you have reason to pass special flags to shutdown.
428    * Otherwise just destroy the socket.
429    *
430    * This method has no effect when a ShutdownSocketSet option is used.
431    *
432    * Returns the result of shutdown on sockets_[n-1]
433    */
434   int stopAccepting(int shutdownFlags = -1);
435
436   /**
437    * Get the maximum number of connections that will be accepted each time
438    * around the event loop.
439    */
440   uint32_t getMaxAcceptAtOnce() const {
441     return maxAcceptAtOnce_;
442   }
443
444   /**
445    * Set the maximum number of connections that will be accepted each time
446    * around the event loop.
447    *
448    * This provides a very coarse-grained way of controlling how fast the
449    * AsyncServerSocket will accept connections.  If you find that when your
450    * server is overloaded AsyncServerSocket accepts connections more quickly
451    * than your code can process them, you can try lowering this number so that
452    * fewer connections will be accepted each event loop iteration.
453    *
454    * For more explicit control over the accept rate, you can also use
455    * pauseAccepting() to temporarily pause accepting when your server is
456    * overloaded, and then use startAccepting() later to resume accepting.
457    */
458   void setMaxAcceptAtOnce(uint32_t numConns) {
459     maxAcceptAtOnce_ = numConns;
460   }
461
462   /**
463    * Get the maximum number of unprocessed messages which a NotificationQueue
464    * can hold.
465    */
466   uint32_t getMaxNumMessagesInQueue() const {
467     return maxNumMsgsInQueue_;
468   }
469
470   /**
471    * Set the maximum number of unprocessed messages in NotificationQueue.
472    * No new message will be sent to that NotificationQueue if there are more
473    * than such number of unprocessed messages in that queue.
474    *
475    * Only works if called before addAcceptCallback.
476    */
477   void setMaxNumMessagesInQueue(uint32_t num) {
478     maxNumMsgsInQueue_ = num;
479   }
480
481   /**
482    * Get the speed of adjusting connection accept rate.
483    */
484   double getAcceptRateAdjustSpeed() const {
485     return acceptRateAdjustSpeed_;
486   }
487
488   /**
489    * Set the speed of adjusting connection accept rate.
490    */
491   void setAcceptRateAdjustSpeed(double speed) {
492     acceptRateAdjustSpeed_ = speed;
493   }
494
495   /**
496    * Get the number of connections dropped by the AsyncServerSocket
497    */
498   uint64_t getNumDroppedConnections() const {
499     return numDroppedConnections_;
500   }
501
502   /**
503    * Set whether or not SO_KEEPALIVE should be enabled on the server socket
504    * (and thus on all subsequently-accepted connections). By default, keepalive
505    * is enabled.
506    *
507    * Note that TCP keepalive usually only kicks in after the connection has
508    * been idle for several hours. Applications should almost always have their
509    * own, shorter idle timeout.
510    */
511   void setKeepAliveEnabled(bool enabled) {
512     keepAliveEnabled_ = enabled;
513
514     for (auto& handler : sockets_) {
515       if (handler.socket_ < 0) {
516         continue;
517       }
518
519       int val = (enabled) ? 1 : 0;
520       if (setsockopt(handler.socket_, SOL_SOCKET,
521                      SO_KEEPALIVE, &val, sizeof(val)) != 0) {
522         LOG(ERROR) << "failed to set SO_KEEPALIVE on async server socket: %s" <<
523                 strerror(errno);
524       }
525     }
526   }
527
528   /**
529    * Get whether or not SO_KEEPALIVE is enabled on the server socket.
530    */
531   bool getKeepAliveEnabled() const {
532     return keepAliveEnabled_;
533   }
534
535   /**
536    * Set whether or not SO_REUSEPORT should be enabled on the server socket,
537    * allowing multiple binds to the same port
538    */
539   void setReusePortEnabled(bool enabled) {
540     reusePortEnabled_ = enabled;
541
542     for (auto& handler : sockets_) {
543       if (handler.socket_ < 0) {
544         continue;
545       }
546
547       int val = (enabled) ? 1 : 0;
548       if (setsockopt(handler.socket_, SOL_SOCKET,
549                      SO_REUSEPORT, &val, sizeof(val)) != 0) {
550         LOG(ERROR) <<
551           "failed to set SO_REUSEPORT on async server socket " << errno;
552         folly::throwSystemError(errno,
553                                 "failed to bind to async server socket");
554       }
555     }
556   }
557
558   /**
559    * Get whether or not SO_REUSEPORT is enabled on the server socket.
560    */
561   bool getReusePortEnabled_() const {
562     return reusePortEnabled_;
563   }
564
565   /**
566    * Set whether or not the socket should close during exec() (FD_CLOEXEC). By
567    * default, this is enabled
568    */
569   void setCloseOnExec(bool closeOnExec) {
570     closeOnExec_ = closeOnExec;
571   }
572
573   /**
574    * Get whether or not FD_CLOEXEC is enabled on the server socket.
575    */
576   bool getCloseOnExec() const {
577     return closeOnExec_;
578   }
579
580  protected:
581   /**
582    * Protected destructor.
583    *
584    * Invoke destroy() instead to destroy the AsyncServerSocket.
585    */
586   virtual ~AsyncServerSocket();
587
588  private:
589   enum class MessageType {
590     MSG_NEW_CONN = 0,
591     MSG_ERROR = 1
592   };
593
594   struct QueueMessage {
595     MessageType type;
596     int fd;
597     int err;
598     SocketAddress address;
599     std::string msg;
600   };
601
602   /**
603    * A class to receive notifications to invoke AcceptCallback objects
604    * in other EventBase threads.
605    *
606    * A RemoteAcceptor object is created for each AcceptCallback that
607    * is installed in a separate EventBase thread.  The RemoteAcceptor
608    * receives notification of new sockets via a NotificationQueue,
609    * and then invokes the AcceptCallback.
610    */
611   class RemoteAcceptor
612       : private NotificationQueue<QueueMessage>::Consumer {
613   public:
614     explicit RemoteAcceptor(AcceptCallback *callback)
615       : callback_(callback) {}
616
617     ~RemoteAcceptor() = default;
618
619     void start(EventBase *eventBase, uint32_t maxAtOnce, uint32_t maxInQueue);
620     void stop(EventBase* eventBase, AcceptCallback* callback);
621
622     virtual void messageAvailable(QueueMessage&& message);
623
624     NotificationQueue<QueueMessage>* getQueue() {
625       return &queue_;
626     }
627
628   private:
629     AcceptCallback *callback_;
630
631     NotificationQueue<QueueMessage> queue_;
632   };
633
634   /**
635    * A struct to keep track of the callbacks associated with this server
636    * socket.
637    */
638   struct CallbackInfo {
639     CallbackInfo(AcceptCallback *cb, EventBase *evb)
640       : callback(cb),
641         eventBase(evb),
642         consumer(nullptr) {}
643
644     AcceptCallback *callback;
645     EventBase *eventBase;
646
647     RemoteAcceptor* consumer;
648   };
649
650   class BackoffTimeout;
651
652   virtual void handlerReady(
653     uint16_t events, int socket, sa_family_t family) noexcept;
654
655   int createSocket(int family);
656   void setupSocket(int fd);
657   void bindSocket(int fd, const SocketAddress& address, bool isExistingSocket);
658   void dispatchSocket(int socket, SocketAddress&& address);
659   void dispatchError(const char *msg, int errnoValue);
660   void enterBackoff();
661   void backoffTimeoutExpired();
662
663   CallbackInfo* nextCallback() {
664     CallbackInfo* info = &callbacks_[callbackIndex_];
665
666     ++callbackIndex_;
667     if (callbackIndex_ >= callbacks_.size()) {
668       callbackIndex_ = 0;
669     }
670
671     return info;
672   }
673
674   struct ServerEventHandler : public EventHandler {
675     ServerEventHandler(EventBase* eventBase, int socket,
676                        AsyncServerSocket* parent,
677                       sa_family_t addressFamily)
678         : EventHandler(eventBase, socket)
679         , eventBase_(eventBase)
680         , socket_(socket)
681         , parent_(parent)
682         , addressFamily_(addressFamily) {}
683
684     ServerEventHandler(const ServerEventHandler& other)
685     : EventHandler(other.eventBase_, other.socket_)
686     , eventBase_(other.eventBase_)
687     , socket_(other.socket_)
688     , parent_(other.parent_)
689     , addressFamily_(other.addressFamily_) {}
690
691     ServerEventHandler& operator=(
692         const ServerEventHandler& other) {
693       if (this != &other) {
694         eventBase_ = other.eventBase_;
695         socket_ = other.socket_;
696         parent_ = other.parent_;
697         addressFamily_ = other.addressFamily_;
698
699         detachEventBase();
700         attachEventBase(other.eventBase_);
701         changeHandlerFD(other.socket_);
702       }
703       return *this;
704     }
705
706     // Inherited from EventHandler
707     virtual void handlerReady(uint16_t events) noexcept {
708       parent_->handlerReady(events, socket_, addressFamily_);
709     }
710
711     EventBase* eventBase_;
712     int socket_;
713     AsyncServerSocket* parent_;
714     sa_family_t addressFamily_;
715   };
716
717   EventBase *eventBase_;
718   std::vector<ServerEventHandler> sockets_;
719   std::vector<int> pendingCloseSockets_;
720   bool accepting_;
721   uint32_t maxAcceptAtOnce_;
722   uint32_t maxNumMsgsInQueue_;
723   double acceptRateAdjustSpeed_;  //0 to disable auto adjust
724   double acceptRate_;
725   std::chrono::time_point<std::chrono::steady_clock> lastAccepTimestamp_;
726   uint64_t numDroppedConnections_;
727   uint32_t callbackIndex_;
728   BackoffTimeout *backoffTimeout_;
729   std::vector<CallbackInfo> callbacks_;
730   bool keepAliveEnabled_;
731   bool reusePortEnabled_{false};
732   bool closeOnExec_;
733   ShutdownSocketSet* shutdownSocketSet_;
734 };
735
736 } // folly