1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 20 #ifndef _THRIFT_TRANSPORT_TSERVERSOCKET_H_ 21 #define _THRIFT_TRANSPORT_TSERVERSOCKET_H_ 1 22 23 #include <thrift/concurrency/Mutex.h> 24 #include <thrift/transport/PlatformSocket.h> 25 #include <thrift/transport/TServerTransport.h> 26 27 #include <sys/types.h> 28 #ifdef HAVE_SYS_SOCKET_H 29 #include <sys/socket.h> 30 #endif 31 #ifdef HAVE_NETDB_H 32 #include <netdb.h> 33 #endif 34 35 namespace apache { 36 namespace thrift { 37 namespace transport { 38 39 class TSocket; 40 41 /** 42 * Server socket implementation of TServerTransport. Wrapper around a unix 43 * socket listen and accept calls. 44 * 45 */ 46 class TServerSocket : public TServerTransport { 47 public: 48 typedef std::function<void(THRIFT_SOCKET fd)> socket_func_t; 49 50 const static int DEFAULT_BACKLOG = 1024; 51 52 /** 53 * Constructor. 54 * 55 * @param port Port number to bind to 56 */ 57 TServerSocket(int port); 58 59 /** 60 * Constructor. 61 * 62 * @param port Port number to bind to 63 * @param sendTimeout Socket send timeout 64 * @param recvTimeout Socket receive timeout 65 */ 66 TServerSocket(int port, int sendTimeout, int recvTimeout); 67 68 /** 69 * Constructor. 70 * 71 * @param address Address to bind to 72 * @param port Port number to bind to 73 */ 74 TServerSocket(const std::string& address, int port); 75 76 /** 77 * Constructor used for unix sockets. 78 * 79 * @param path Pathname for unix socket. 80 */ 81 TServerSocket(const std::string& path); 82 83 ~TServerSocket() override; 84 85 86 bool isOpen() const override; 87 88 void setSendTimeout(int sendTimeout); 89 void setRecvTimeout(int recvTimeout); 90 91 void setAcceptTimeout(int accTimeout); 92 void setAcceptBacklog(int accBacklog); 93 94 void setRetryLimit(int retryLimit); 95 void setRetryDelay(int retryDelay); 96 setKeepAlive(bool keepAlive)97 void setKeepAlive(bool keepAlive) { keepAlive_ = keepAlive; } 98 99 void setTcpSendBuffer(int tcpSendBuffer); 100 void setTcpRecvBuffer(int tcpRecvBuffer); 101 102 // listenCallback gets called just before listen, and after all Thrift 103 // setsockopt calls have been made. If you have custom setsockopt 104 // things that need to happen on the listening socket, this is the place to do it. setListenCallback(const socket_func_t & listenCallback)105 void setListenCallback(const socket_func_t& listenCallback) { listenCallback_ = listenCallback; } 106 107 // acceptCallback gets called after each accept call, on the newly created socket. 108 // It is called after all Thrift setsockopt calls have been made. If you have 109 // custom setsockopt things that need to happen on the accepted 110 // socket, this is the place to do it. setAcceptCallback(const socket_func_t & acceptCallback)111 void setAcceptCallback(const socket_func_t& acceptCallback) { acceptCallback_ = acceptCallback; } 112 113 // When enabled (the default), new children TSockets will be constructed so 114 // they can be interrupted by TServerTransport::interruptChildren(). 115 // This is more expensive in terms of system calls (poll + recv) however 116 // ensures a connected client cannot interfere with TServer::stop(). 117 // 118 // When disabled, TSocket children do not incur an additional poll() call. 119 // Server-side reads are more efficient, however a client can interfere with 120 // the server's ability to shutdown properly by staying connected. 121 // 122 // Must be called before listen(); mode cannot be switched after that. 123 // \throws std::logic_error if listen() has been called 124 void setInterruptableChildren(bool enable); 125 getSocketFD()126 THRIFT_SOCKET getSocketFD() override { return serverSocket_; } 127 128 int getPort(); 129 130 void listen() override; 131 void interrupt() override; 132 void interruptChildren() override; 133 void close() override; 134 135 protected: 136 std::shared_ptr<TTransport> acceptImpl() override; 137 virtual std::shared_ptr<TSocket> createSocket(THRIFT_SOCKET client); 138 bool interruptableChildren_; 139 std::shared_ptr<THRIFT_SOCKET> pChildInterruptSockReader_; // if interruptableChildren_ this is shared with child TSockets 140 141 private: 142 void notify(THRIFT_SOCKET notifySock); 143 void _setup_sockopts(); 144 void _setup_unixdomain_sockopts(); 145 void _setup_tcp_sockopts(); 146 147 int port_; 148 std::string address_; 149 std::string path_; 150 THRIFT_SOCKET serverSocket_; 151 int acceptBacklog_; 152 int sendTimeout_; 153 int recvTimeout_; 154 int accTimeout_; 155 int retryLimit_; 156 int retryDelay_; 157 int tcpSendBuffer_; 158 int tcpRecvBuffer_; 159 bool keepAlive_; 160 bool listening_; 161 162 concurrency::Mutex rwMutex_; // thread-safe interrupt 163 THRIFT_SOCKET interruptSockWriter_; // is notified on interrupt() 164 THRIFT_SOCKET interruptSockReader_; // is used in select/poll with serverSocket_ for interruptability 165 THRIFT_SOCKET childInterruptSockWriter_; // is notified on interruptChildren() 166 167 socket_func_t listenCallback_; 168 socket_func_t acceptCallback_; 169 }; 170 } 171 } 172 } // apache::thrift::transport 173 174 #endif // #ifndef _THRIFT_TRANSPORT_TSERVERSOCKET_H_ 175