diff options
Diffstat (limited to 'src/mongo/util/net/listen.h')
-rw-r--r-- | src/mongo/util/net/listen.h | 241 |
1 files changed, 121 insertions, 120 deletions
diff --git a/src/mongo/util/net/listen.h b/src/mongo/util/net/listen.h index 546ef223bf4..390c23bc443 100644 --- a/src/mongo/util/net/listen.h +++ b/src/mongo/util/net/listen.h @@ -42,128 +42,129 @@ namespace mongo { - const int DEFAULT_MAX_CONN = 1000000; - - class MessagingPort; - - class Listener { - MONGO_DISALLOW_COPYING(Listener); - public: - - Listener(const std::string& name, const std::string &ip, int port, bool logConnect=true ); - - virtual ~Listener(); - - void initAndListen(); // never returns unless error (start a thread) - - /* spawn a thread, etc., then return */ - virtual void accepted(std::shared_ptr<Socket> psocket, long long connectionId ); - virtual void acceptedMP(MessagingPort *mp); - - const int _port; - - /** - * @return a rough estimate of elapsed time since the server started - todo: - 1) consider adding some sort of relaxedLoad semantic to the reading here of - _elapsedTime - 2) curTimeMillis() implementations have gotten faster. consider eliminating - this code? would have to measure it first. if eliminated be careful if - syscall used isn't skewable. Note also if #2 is done, listen() doesn't - then have to keep waking up and maybe that helps on a developer's laptop - battery usage... - */ - long long getMyElapsedTimeMillis() const { return _elapsedTime; } - - /** - * Allocate sockets for the listener and set _setupSocketsSuccessful to true - * iff the process was successful. - */ - void setupSockets(); - - void setAsTimeTracker() { - _timeTracker = this; - } - - // TODO(spencer): Remove this and get the global Listener via the - // globalEnvironmentExperiment - static const Listener* getTimeTracker() { - return _timeTracker; - } - - static long long getElapsedTimeMillis() { - if ( _timeTracker ) - return _timeTracker->getMyElapsedTimeMillis(); - - // should this assert or throw? seems like callers may not expect to get zero back, certainly not forever. - return 0; - } - - /** - * Blocks until initAndListen has been called on this instance and gotten far enough that - * it is ready to receive incoming network requests. - */ - void waitUntilListening() const; - - private: - std::vector<SockAddr> _mine; - std::vector<SOCKET> _socks; - std::string _name; - std::string _ip; - bool _setupSocketsSuccessful; - bool _logConnect; - long long _elapsedTime; - mutable stdx::mutex _readyMutex; // Protects _ready - mutable stdx::condition_variable _readyCondition; // Used to wait for changes to _ready - // Boolean that indicates whether this Listener is ready to accept incoming network requests - bool _ready; +const int DEFAULT_MAX_CONN = 1000000; + +class MessagingPort; + +class Listener { + MONGO_DISALLOW_COPYING(Listener); + +public: + Listener(const std::string& name, const std::string& ip, int port, bool logConnect = true); + + virtual ~Listener(); + + void initAndListen(); // never returns unless error (start a thread) + + /* spawn a thread, etc., then return */ + virtual void accepted(std::shared_ptr<Socket> psocket, long long connectionId); + virtual void acceptedMP(MessagingPort* mp); + + const int _port; + + /** + * @return a rough estimate of elapsed time since the server started + todo: + 1) consider adding some sort of relaxedLoad semantic to the reading here of + _elapsedTime + 2) curTimeMillis() implementations have gotten faster. consider eliminating + this code? would have to measure it first. if eliminated be careful if + syscall used isn't skewable. Note also if #2 is done, listen() doesn't + then have to keep waking up and maybe that helps on a developer's laptop + battery usage... + */ + long long getMyElapsedTimeMillis() const { + return _elapsedTime; + } + + /** + * Allocate sockets for the listener and set _setupSocketsSuccessful to true + * iff the process was successful. + */ + void setupSockets(); + + void setAsTimeTracker() { + _timeTracker = this; + } + + // TODO(spencer): Remove this and get the global Listener via the + // globalEnvironmentExperiment + static const Listener* getTimeTracker() { + return _timeTracker; + } + + static long long getElapsedTimeMillis() { + if (_timeTracker) + return _timeTracker->getMyElapsedTimeMillis(); + + // should this assert or throw? seems like callers may not expect to get zero back, certainly not forever. + return 0; + } + + /** + * Blocks until initAndListen has been called on this instance and gotten far enough that + * it is ready to receive incoming network requests. + */ + void waitUntilListening() const; + +private: + std::vector<SockAddr> _mine; + std::vector<SOCKET> _socks; + std::string _name; + std::string _ip; + bool _setupSocketsSuccessful; + bool _logConnect; + long long _elapsedTime; + mutable stdx::mutex _readyMutex; // Protects _ready + mutable stdx::condition_variable _readyCondition; // Used to wait for changes to _ready + // Boolean that indicates whether this Listener is ready to accept incoming network requests + bool _ready; #ifdef MONGO_CONFIG_SSL - SSLManagerInterface* _ssl; + SSLManagerInterface* _ssl; #endif - void _logListen( int port , bool ssl ); - - static const Listener* _timeTracker; - - virtual bool useUnixSockets() const { return false; } - - public: - /** the "next" connection number. every connection to this process has a unique number */ - static AtomicInt64 globalConnectionNumber; - - /** keeps track of how many allowed connections there are and how many are being used*/ - static TicketHolder globalTicketHolder; - - /** makes sure user input is sane */ - static void checkTicketNumbers(); - }; - - class ListeningSockets { - public: - ListeningSockets() - : _sockets( new std::set<int>() ) - , _socketPaths( new std::set<std::string>() ) - { } - void add( int sock ) { - stdx::lock_guard<stdx::mutex> lk( _mutex ); - _sockets->insert( sock ); - } - void addPath( const std::string& path ) { - stdx::lock_guard<stdx::mutex> lk( _mutex ); - _socketPaths->insert( path ); - } - void remove( int sock ) { - stdx::lock_guard<stdx::mutex> lk( _mutex ); - _sockets->erase( sock ); - } - void closeAll(); - static ListeningSockets* get(); - private: - stdx::mutex _mutex; - std::set<int>* _sockets; - std::set<std::string>* _socketPaths; // for unix domain sockets - static ListeningSockets* _instance; - }; - + void _logListen(int port, bool ssl); + + static const Listener* _timeTracker; + + virtual bool useUnixSockets() const { + return false; + } + +public: + /** the "next" connection number. every connection to this process has a unique number */ + static AtomicInt64 globalConnectionNumber; + + /** keeps track of how many allowed connections there are and how many are being used*/ + static TicketHolder globalTicketHolder; + + /** makes sure user input is sane */ + static void checkTicketNumbers(); +}; + +class ListeningSockets { +public: + ListeningSockets() : _sockets(new std::set<int>()), _socketPaths(new std::set<std::string>()) {} + void add(int sock) { + stdx::lock_guard<stdx::mutex> lk(_mutex); + _sockets->insert(sock); + } + void addPath(const std::string& path) { + stdx::lock_guard<stdx::mutex> lk(_mutex); + _socketPaths->insert(path); + } + void remove(int sock) { + stdx::lock_guard<stdx::mutex> lk(_mutex); + _sockets->erase(sock); + } + void closeAll(); + static ListeningSockets* get(); + +private: + stdx::mutex _mutex; + std::set<int>* _sockets; + std::set<std::string>* _socketPaths; // for unix domain sockets + static ListeningSockets* _instance; +}; } |