blob: 428dc1b8aeed06f8878f68f685187b3ca06b03a9 [file] [log] [blame]
Mark Slee9f0c6512007-02-28 23:58:26 +00001// Copyright (c) 2006- Facebook
2// Distributed under the Thrift Software License
3//
4// See accompanying file LICENSE or visit the Thrift site at:
5// http://developers.facebook.com/thrift/
6
David Reissc88eb8c2008-06-11 01:18:54 +00007#include <cstring>
Mark Sleee8540632006-05-30 09:24:40 +00008#include <sys/socket.h>
David Reiss1677ac92008-04-08 06:26:27 +00009#include <sys/poll.h>
Mark Sleedd564972007-08-21 02:39:57 +000010#include <sys/types.h>
Mark Sleee8540632006-05-30 09:24:40 +000011#include <netinet/in.h>
Mark Slee29050782006-09-29 00:12:30 +000012#include <netinet/tcp.h>
Mark Slee6d56eb92007-07-06 22:28:15 +000013#include <netdb.h>
Mark Sleea5a783f2007-03-02 19:41:08 +000014#include <fcntl.h>
Mark Slee8d7e1f62006-06-07 06:48:56 +000015#include <errno.h>
Mark Sleee8540632006-05-30 09:24:40 +000016
Marc Slemkod42a2c22006-08-10 03:30:18 +000017#include "TSocket.h"
18#include "TServerSocket.h"
Marc Slemko16698852006-08-04 03:16:10 +000019#include <boost/shared_ptr.hpp>
Mark Sleee8540632006-05-30 09:24:40 +000020
Mark Slee256bdc42007-11-27 08:42:19 +000021namespace facebook { namespace thrift { namespace transport {
Marc Slemko6f038a72006-08-03 18:58:09 +000022
Martin Kraemere6c4fa62007-07-09 19:08:25 +000023using namespace std;
David Reissd4a269c2007-08-23 02:37:19 +000024using boost::shared_ptr;
Marc Slemko16698852006-08-04 03:16:10 +000025
Mark Sleee8540632006-05-30 09:24:40 +000026TServerSocket::TServerSocket(int port) :
Mark Slee29050782006-09-29 00:12:30 +000027 port_(port),
Martin Kraemeree341cb2007-02-05 21:40:38 +000028 serverSocket_(-1),
Mark Slee29050782006-09-29 00:12:30 +000029 acceptBacklog_(1024),
30 sendTimeout_(0),
Mark Sleea5a783f2007-03-02 19:41:08 +000031 recvTimeout_(0),
boz1ea81ce2007-05-14 23:04:33 +000032 retryLimit_(0),
33 retryDelay_(0),
Christopher Piro9cc63b52008-03-21 00:40:42 +000034 tcpSendBuffer_(0),
35 tcpRecvBuffer_(0),
Mark Slee561b5362007-03-09 19:26:29 +000036 intSock1_(-1),
37 intSock2_(-1) {}
Mark Slee29050782006-09-29 00:12:30 +000038
39TServerSocket::TServerSocket(int port, int sendTimeout, int recvTimeout) :
40 port_(port),
Martin Kraemeree341cb2007-02-05 21:40:38 +000041 serverSocket_(-1),
Mark Slee29050782006-09-29 00:12:30 +000042 acceptBacklog_(1024),
43 sendTimeout_(sendTimeout),
Mark Sleea5a783f2007-03-02 19:41:08 +000044 recvTimeout_(recvTimeout),
boz1ea81ce2007-05-14 23:04:33 +000045 retryLimit_(0),
46 retryDelay_(0),
Christopher Piro9cc63b52008-03-21 00:40:42 +000047 tcpSendBuffer_(0),
48 tcpRecvBuffer_(0),
Mark Slee561b5362007-03-09 19:26:29 +000049 intSock1_(-1),
50 intSock2_(-1) {}
Mark Sleee8540632006-05-30 09:24:40 +000051
52TServerSocket::~TServerSocket() {
53 close();
54}
55
Mark Slee29050782006-09-29 00:12:30 +000056void TServerSocket::setSendTimeout(int sendTimeout) {
57 sendTimeout_ = sendTimeout;
58}
59
60void TServerSocket::setRecvTimeout(int recvTimeout) {
61 recvTimeout_ = recvTimeout;
62}
63
boz1ea81ce2007-05-14 23:04:33 +000064void TServerSocket::setRetryLimit(int retryLimit) {
65 retryLimit_ = retryLimit;
66}
67
68void TServerSocket::setRetryDelay(int retryDelay) {
69 retryDelay_ = retryDelay;
70}
71
Christopher Piro9cc63b52008-03-21 00:40:42 +000072void TServerSocket::setTcpSendBuffer(int tcpSendBuffer) {
73 tcpSendBuffer_ = tcpSendBuffer;
74}
75
76void TServerSocket::setTcpRecvBuffer(int tcpRecvBuffer) {
77 tcpRecvBuffer_ = tcpRecvBuffer;
78}
79
Mark Slee8d7e1f62006-06-07 06:48:56 +000080void TServerSocket::listen() {
Mark Slee561b5362007-03-09 19:26:29 +000081 int sv[2];
82 if (-1 == socketpair(AF_LOCAL, SOCK_STREAM, 0, sv)) {
David Reiss9b209552008-04-08 06:26:05 +000083 int errno_copy = errno;
84 string errStr = "TServerSocket::listen() socketpair() " + TOutput::strerror_s(errno_copy);
85 GlobalOutput(errStr.c_str());
Mark Slee561b5362007-03-09 19:26:29 +000086 intSock1_ = -1;
87 intSock2_ = -1;
88 } else {
Mark Sleee02385b2007-06-09 01:21:16 +000089 intSock1_ = sv[1];
90 intSock2_ = sv[0];
Mark Slee561b5362007-03-09 19:26:29 +000091 }
92
Mark Slee6d56eb92007-07-06 22:28:15 +000093 struct addrinfo hints, *res, *res0;
94 int error;
95 char port[sizeof("65536") + 1];
David Reissc88eb8c2008-06-11 01:18:54 +000096 std::memset(&hints, 0, sizeof(hints));
Mark Slee6d56eb92007-07-06 22:28:15 +000097 hints.ai_family = PF_UNSPEC;
98 hints.ai_socktype = SOCK_STREAM;
Mark Slee256bdc42007-11-27 08:42:19 +000099 hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
Mark Slee6d56eb92007-07-06 22:28:15 +0000100 sprintf(port, "%d", port_);
101
102 // Wildcard address
103 error = getaddrinfo(NULL, port, &hints, &res0);
104 if (error) {
105 fprintf(stderr, "getaddrinfo %d: %s\n", error, gai_strerror(error));
106 close();
107 throw TTransportException(TTransportException::NOT_OPEN, "Could not resolve host for server socket.");
108 }
109
110 // Pick the ipv6 address first since ipv4 addresses can be mapped
111 // into ipv6 space.
112 for (res = res0; res; res = res->ai_next) {
113 if (res->ai_family == AF_INET6 || res->ai_next == NULL)
114 break;
115 }
Mark Slee256bdc42007-11-27 08:42:19 +0000116
Mark Slee6d56eb92007-07-06 22:28:15 +0000117 serverSocket_ = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
Mark Sleee8540632006-05-30 09:24:40 +0000118 if (serverSocket_ == -1) {
David Reiss9b209552008-04-08 06:26:05 +0000119 int errno_copy = errno;
120 string errStr = "TServerSocket::listen() socket() " + TOutput::strerror_s(errno_copy);
121 GlobalOutput(errStr.c_str());
Mark Sleee8540632006-05-30 09:24:40 +0000122 close();
David Reiss9b209552008-04-08 06:26:05 +0000123 throw TTransportException(TTransportException::NOT_OPEN, "Could not create server socket.", errno_copy);
Mark Sleee8540632006-05-30 09:24:40 +0000124 }
125
126 // Set reusaddress to prevent 2MSL delay on accept
127 int one = 1;
128 if (-1 == setsockopt(serverSocket_, SOL_SOCKET, SO_REUSEADDR,
129 &one, sizeof(one))) {
David Reiss9b209552008-04-08 06:26:05 +0000130 int errno_copy = errno;
131 string errStr = "TServerSocket::listen() setsockopt() SO_REUSEADDR " + TOutput::strerror_s(errno_copy);
132 GlobalOutput(errStr.c_str());
Mark Sleee8540632006-05-30 09:24:40 +0000133 close();
David Reiss9b209552008-04-08 06:26:05 +0000134 throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_REUSEADDR", errno_copy);
Mark Sleee8540632006-05-30 09:24:40 +0000135 }
136
Christopher Piro9cc63b52008-03-21 00:40:42 +0000137 // Set TCP buffer sizes
138 if (tcpSendBuffer_ > 0) {
139 if (-1 == setsockopt(serverSocket_, SOL_SOCKET, SO_SNDBUF,
140 &tcpSendBuffer_, sizeof(tcpSendBuffer_))) {
David Reiss9b209552008-04-08 06:26:05 +0000141 int errno_copy = errno;
142 string errStr = "TServerSocket::listen() setsockopt() SO_SNDBUF " + TOutput::strerror_s(errno_copy);
143 GlobalOutput(errStr.c_str());
Christopher Piro9cc63b52008-03-21 00:40:42 +0000144 close();
David Reiss9b209552008-04-08 06:26:05 +0000145 throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_SNDBUF", errno_copy);
Christopher Piro9cc63b52008-03-21 00:40:42 +0000146 }
147 }
148
149 if (tcpRecvBuffer_ > 0) {
150 if (-1 == setsockopt(serverSocket_, SOL_SOCKET, SO_RCVBUF,
151 &tcpRecvBuffer_, sizeof(tcpRecvBuffer_))) {
David Reiss9b209552008-04-08 06:26:05 +0000152 int errno_copy = errno;
153 string errStr = "TServerSocket::listen() setsockopt() SO_RCVBUF " + TOutput::strerror_s(errno_copy);
154 GlobalOutput(errStr.c_str());
Christopher Piro9cc63b52008-03-21 00:40:42 +0000155 close();
David Reiss9b209552008-04-08 06:26:05 +0000156 throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_RCVBUF", errno_copy);
Christopher Piro9cc63b52008-03-21 00:40:42 +0000157 }
158 }
159
Mark Slee29050782006-09-29 00:12:30 +0000160 // Defer accept
161 #ifdef TCP_DEFER_ACCEPT
162 if (-1 == setsockopt(serverSocket_, SOL_SOCKET, TCP_DEFER_ACCEPT,
163 &one, sizeof(one))) {
David Reiss9b209552008-04-08 06:26:05 +0000164 int errno_copy = errno;
165 string errStr = "TServerSocket::listen() setsockopt() TCP_DEFER_ACCEPT " + TOutput::strerror_s(errno_copy);
166 GlobalOutput(errStr.c_str());
Mark Slee29050782006-09-29 00:12:30 +0000167 close();
David Reiss9b209552008-04-08 06:26:05 +0000168 throw TTransportException(TTransportException::NOT_OPEN, "Could not set TCP_DEFER_ACCEPT", errno_copy);
Mark Slee29050782006-09-29 00:12:30 +0000169 }
170 #endif // #ifdef TCP_DEFER_ACCEPT
171
David Reiss13aea462008-06-10 22:56:04 +0000172 #ifdef IPV6_V6ONLY
173 int zero = 0;
David Reiss1a2f2182008-06-11 01:14:01 +0000174 if (-1 == setsockopt(serverSocket_, IPPROTO_IPV6, IPV6_V6ONLY,
David Reiss13aea462008-06-10 22:56:04 +0000175 &zero, sizeof(zero))) {
176 GlobalOutput("TServerSocket::listen() IPV6_V6ONLY");
177 }
178 #endif // #ifdef IPV6_V6ONLY
179
Mark Sleee8540632006-05-30 09:24:40 +0000180 // Turn linger off, don't want to block on calls to close
181 struct linger ling = {0, 0};
182 if (-1 == setsockopt(serverSocket_, SOL_SOCKET, SO_LINGER,
183 &ling, sizeof(ling))) {
David Reiss9b209552008-04-08 06:26:05 +0000184 int errno_copy = errno;
185 string errStr = "TServerSocket::listen() setsockopt() SO_LINGER " + TOutput::strerror_s(errno_copy);
186 GlobalOutput(errStr.c_str());
Mark Sleee8540632006-05-30 09:24:40 +0000187 close();
David Reiss9b209552008-04-08 06:26:05 +0000188 throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_LINGER", errno_copy);
Mark Sleee8540632006-05-30 09:24:40 +0000189 }
190
Mark Slee29050782006-09-29 00:12:30 +0000191 // TCP Nodelay, speed over bandwidth
192 if (-1 == setsockopt(serverSocket_, IPPROTO_TCP, TCP_NODELAY,
193 &one, sizeof(one))) {
David Reiss9b209552008-04-08 06:26:05 +0000194 int errno_copy = errno;
195 string errStr = "TServerSocket::listen() setsockopt() TCP_NODELAY " + TOutput::strerror_s(errno_copy);
196 GlobalOutput(errStr.c_str());
Mark Slee29050782006-09-29 00:12:30 +0000197 close();
David Reiss9b209552008-04-08 06:26:05 +0000198 throw TTransportException(TTransportException::NOT_OPEN, "Could not set TCP_NODELAY", errno_copy);
Mark Slee29050782006-09-29 00:12:30 +0000199 }
200
Mark Sleea5a783f2007-03-02 19:41:08 +0000201 // Set NONBLOCK on the accept socket
202 int flags = fcntl(serverSocket_, F_GETFL, 0);
203 if (flags == -1) {
David Reiss9b209552008-04-08 06:26:05 +0000204 int errno_copy = errno;
205 string errStr = "TServerSocket::listen() fcntl() F_GETFL " + TOutput::strerror_s(errno_copy);
206 GlobalOutput(errStr.c_str());
207 throw TTransportException(TTransportException::NOT_OPEN, "fcntl() failed", errno_copy);
Mark Sleea5a783f2007-03-02 19:41:08 +0000208 }
Mark Slee561b5362007-03-09 19:26:29 +0000209
Mark Sleea5a783f2007-03-02 19:41:08 +0000210 if (-1 == fcntl(serverSocket_, F_SETFL, flags | O_NONBLOCK)) {
David Reiss9b209552008-04-08 06:26:05 +0000211 int errno_copy = errno;
212 string errStr = "TServerSocket::listen() fcntl() O_NONBLOCK " + TOutput::strerror_s(errno_copy);
213 GlobalOutput(errStr.c_str());
214 throw TTransportException(TTransportException::NOT_OPEN, "fcntl() failed", errno_copy);
Mark Sleea5a783f2007-03-02 19:41:08 +0000215 }
216
boz1ea81ce2007-05-14 23:04:33 +0000217 // prepare the port information
Mark Slee256bdc42007-11-27 08:42:19 +0000218 // we may want to try to bind more than once, since SO_REUSEADDR doesn't
boz1ea81ce2007-05-14 23:04:33 +0000219 // always seem to work. The client can configure the retry variables.
220 int retries = 0;
221 do {
Mark Slee6d56eb92007-07-06 22:28:15 +0000222 if (0 == bind(serverSocket_, res->ai_addr, res->ai_addrlen)) {
boz1ea81ce2007-05-14 23:04:33 +0000223 break;
224 }
225
226 // use short circuit evaluation here to only sleep if we need to
227 } while ((retries++ < retryLimit_) && (sleep(retryDelay_) == 0));
228
Mark Slee6d56eb92007-07-06 22:28:15 +0000229 // free addrinfo
230 freeaddrinfo(res0);
Mark Slee256bdc42007-11-27 08:42:19 +0000231
boz1ea81ce2007-05-14 23:04:33 +0000232 // throw an error if we failed to bind properly
233 if (retries > retryLimit_) {
Mark Sleee8540632006-05-30 09:24:40 +0000234 char errbuf[1024];
235 sprintf(errbuf, "TServerSocket::listen() BIND %d", port_);
boz6ded7752007-06-05 22:41:18 +0000236 GlobalOutput(errbuf);
Mark Sleee8540632006-05-30 09:24:40 +0000237 close();
Mark Sleef9831082007-02-20 20:59:21 +0000238 throw TTransportException(TTransportException::NOT_OPEN, "Could not bind");
Mark Sleee8540632006-05-30 09:24:40 +0000239 }
240
241 // Call listen
242 if (-1 == ::listen(serverSocket_, acceptBacklog_)) {
David Reiss9b209552008-04-08 06:26:05 +0000243 int errno_copy = errno;
244 string errStr = "TServerSocket::listen() listen() " + TOutput::strerror_s(errno_copy);
245 GlobalOutput(errStr.c_str());
Mark Sleee8540632006-05-30 09:24:40 +0000246 close();
David Reiss9b209552008-04-08 06:26:05 +0000247 throw TTransportException(TTransportException::NOT_OPEN, "Could not listen", errno_copy);
Mark Sleee8540632006-05-30 09:24:40 +0000248 }
249
250 // The socket is now listening!
Mark Sleee8540632006-05-30 09:24:40 +0000251}
252
Marc Slemko16698852006-08-04 03:16:10 +0000253shared_ptr<TTransport> TServerSocket::acceptImpl() {
Martin Kraemer10640d82007-02-03 01:59:12 +0000254 if (serverSocket_ < 0) {
Mark Sleef9831082007-02-20 20:59:21 +0000255 throw TTransportException(TTransportException::NOT_OPEN, "TServerSocket not listening");
Mark Sleee8540632006-05-30 09:24:40 +0000256 }
257
David Reiss1677ac92008-04-08 06:26:27 +0000258 struct pollfd fds[2];
Mark Sleea5a783f2007-03-02 19:41:08 +0000259
Aditya Agarwal7859a572007-05-31 01:33:07 +0000260 int maxEintrs = 5;
261 int numEintrs = 0;
262
Mark Sleea5a783f2007-03-02 19:41:08 +0000263 while (true) {
David Reissc88eb8c2008-06-11 01:18:54 +0000264 std::memset(fds, 0 , sizeof(fds));
David Reiss1677ac92008-04-08 06:26:27 +0000265 fds[0].fd = serverSocket_;
266 fds[0].events = POLLIN;
Mark Slee561b5362007-03-09 19:26:29 +0000267 if (intSock2_ >= 0) {
David Reiss1677ac92008-04-08 06:26:27 +0000268 fds[1].fd = intSock2_;
David Reiss2724c7a2008-04-18 17:48:03 +0000269 fds[1].events = POLLIN;
Mark Sleea5a783f2007-03-02 19:41:08 +0000270 }
David Reiss1677ac92008-04-08 06:26:27 +0000271 int ret = poll(fds, 2, -1);
Mark Sleea5a783f2007-03-02 19:41:08 +0000272
Mark Slee561b5362007-03-09 19:26:29 +0000273 if (ret < 0) {
Aditya Agarwal7859a572007-05-31 01:33:07 +0000274 // error cases
bozf83c9db2007-05-31 23:38:37 +0000275 if (errno == EINTR && (numEintrs++ < maxEintrs)) {
Mark Slee256bdc42007-11-27 08:42:19 +0000276 // EINTR needs to be handled manually and we can tolerate
Aditya Agarwal7859a572007-05-31 01:33:07 +0000277 // a certain number
278 continue;
279 }
David Reiss9b209552008-04-08 06:26:05 +0000280 int errno_copy = errno;
281 string errStr = "TServerSocket::acceptImpl() poll() " + TOutput::strerror_s(errno_copy);
282 GlobalOutput(errStr.c_str());
283 throw TTransportException(TTransportException::UNKNOWN, "Unknown", errno_copy);
Mark Slee561b5362007-03-09 19:26:29 +0000284 } else if (ret > 0) {
285 // Check for an interrupt signal
David Reiss1677ac92008-04-08 06:26:27 +0000286 if (intSock2_ >= 0 && (fds[1].revents & POLLIN)) {
Mark Slee561b5362007-03-09 19:26:29 +0000287 int8_t buf;
288 if (-1 == recv(intSock2_, &buf, sizeof(int8_t), 0)) {
David Reiss9b209552008-04-08 06:26:05 +0000289 int errno_copy = errno;
290 string errStr = "TServerSocket::acceptImpl() recv() interrupt " + TOutput::strerror_s(errno_copy);
291 GlobalOutput(errStr.c_str());
Mark Slee561b5362007-03-09 19:26:29 +0000292 }
293 throw TTransportException(TTransportException::INTERRUPTED);
294 }
David Reiss9b209552008-04-08 06:26:05 +0000295
Mark Slee561b5362007-03-09 19:26:29 +0000296 // Check for the actual server socket being ready
David Reiss1677ac92008-04-08 06:26:27 +0000297 if (fds[0].revents & POLLIN) {
Mark Slee561b5362007-03-09 19:26:29 +0000298 break;
299 }
300 } else {
David Reiss1677ac92008-04-08 06:26:27 +0000301 GlobalOutput("TServerSocket::acceptImpl() poll 0");
Mark Slee256bdc42007-11-27 08:42:19 +0000302 throw TTransportException(TTransportException::UNKNOWN);
Mark Sleea5a783f2007-03-02 19:41:08 +0000303 }
304 }
305
Mark Slee6d56eb92007-07-06 22:28:15 +0000306 struct sockaddr_storage clientAddress;
Mark Sleee8540632006-05-30 09:24:40 +0000307 int size = sizeof(clientAddress);
308 int clientSocket = ::accept(serverSocket_,
309 (struct sockaddr *) &clientAddress,
310 (socklen_t *) &size);
Mark Slee256bdc42007-11-27 08:42:19 +0000311
Martin Kraemeree341cb2007-02-05 21:40:38 +0000312 if (clientSocket < 0) {
David Reissbc3dddb2007-08-22 23:20:24 +0000313 int errno_copy = errno;
David Reiss9b209552008-04-08 06:26:05 +0000314 string errStr = "TServerSocket::acceptImpl() ::accept() " + TOutput::strerror_s(errno_copy);
315 GlobalOutput(errStr.c_str());
David Reissbc3dddb2007-08-22 23:20:24 +0000316 throw TTransportException(TTransportException::UNKNOWN, "accept()", errno_copy);
Mark Sleee8540632006-05-30 09:24:40 +0000317 }
Mark Sleea5a783f2007-03-02 19:41:08 +0000318
319 // Make sure client socket is blocking
320 int flags = fcntl(clientSocket, F_GETFL, 0);
321 if (flags == -1) {
David Reissbc3dddb2007-08-22 23:20:24 +0000322 int errno_copy = errno;
David Reiss9b209552008-04-08 06:26:05 +0000323 string errStr = "TServerSocket::acceptImpl() fcntl() F_GETFL " + TOutput::strerror_s(errno_copy);
324 GlobalOutput(errStr.c_str());
David Reissbc3dddb2007-08-22 23:20:24 +0000325 throw TTransportException(TTransportException::UNKNOWN, "fcntl(F_GETFL)", errno_copy);
Mark Sleea5a783f2007-03-02 19:41:08 +0000326 }
David Reiss9b209552008-04-08 06:26:05 +0000327
Mark Sleea5a783f2007-03-02 19:41:08 +0000328 if (-1 == fcntl(clientSocket, F_SETFL, flags & ~O_NONBLOCK)) {
David Reissbc3dddb2007-08-22 23:20:24 +0000329 int errno_copy = errno;
David Reiss9b209552008-04-08 06:26:05 +0000330 string errStr = "TServerSocket::acceptImpl() fcntl() F_SETFL ~O_NONBLOCK " + TOutput::strerror_s(errno_copy);
331 GlobalOutput(errStr.c_str());
David Reissbc3dddb2007-08-22 23:20:24 +0000332 throw TTransportException(TTransportException::UNKNOWN, "fcntl(F_SETFL)", errno_copy);
Mark Sleea5a783f2007-03-02 19:41:08 +0000333 }
Mark Slee256bdc42007-11-27 08:42:19 +0000334
Mark Slee29050782006-09-29 00:12:30 +0000335 shared_ptr<TSocket> client(new TSocket(clientSocket));
336 if (sendTimeout_ > 0) {
337 client->setSendTimeout(sendTimeout_);
338 }
339 if (recvTimeout_ > 0) {
340 client->setRecvTimeout(recvTimeout_);
Mark Sleea5a783f2007-03-02 19:41:08 +0000341 }
Mark Slee256bdc42007-11-27 08:42:19 +0000342
Mark Slee29050782006-09-29 00:12:30 +0000343 return client;
Mark Sleee8540632006-05-30 09:24:40 +0000344}
345
Mark Slee561b5362007-03-09 19:26:29 +0000346void TServerSocket::interrupt() {
347 if (intSock1_ >= 0) {
348 int8_t byte = 0;
349 if (-1 == send(intSock1_, &byte, sizeof(int8_t), 0)) {
David Reiss9b209552008-04-08 06:26:05 +0000350 int errno_copy = errno;
351 string errStr = "TServerSocket::interrupt() send() " + TOutput::strerror_s(errno_copy);
352 GlobalOutput(errStr.c_str());
Mark Slee561b5362007-03-09 19:26:29 +0000353 }
354 }
355}
356
Mark Sleee8540632006-05-30 09:24:40 +0000357void TServerSocket::close() {
Martin Kraemeree341cb2007-02-05 21:40:38 +0000358 if (serverSocket_ >= 0) {
Mark Sleee8540632006-05-30 09:24:40 +0000359 shutdown(serverSocket_, SHUT_RDWR);
360 ::close(serverSocket_);
361 }
Mark Slee561b5362007-03-09 19:26:29 +0000362 if (intSock1_ >= 0) {
363 ::close(intSock1_);
364 }
365 if (intSock2_ >= 0) {
366 ::close(intSock2_);
367 }
Martin Kraemeree341cb2007-02-05 21:40:38 +0000368 serverSocket_ = -1;
Mark Slee561b5362007-03-09 19:26:29 +0000369 intSock1_ = -1;
370 intSock2_ = -1;
Mark Sleee8540632006-05-30 09:24:40 +0000371}
Marc Slemko6f038a72006-08-03 18:58:09 +0000372
373}}} // facebook::thrift::transport