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