- VERIFY(close(pipe_[1]) == 0);
- VERIFY(pthread_join(th_, NULL) == 0);
-
- //close all the active connections
- std::map<int, connection *>::iterator i;
- for (i = conns_.begin(); i != conns_.end(); i++) {
- i->second->closeconn();
- i->second->decref();
- }
+ struct sockaddr_in sin;
+ memset(&sin, 0, sizeof(sin));
+ sin.sin_family = AF_INET;
+ sin.sin_port = hton(port);
+
+ tcp_ = socket(AF_INET, SOCK_STREAM, 0);
+ if (tcp_ < 0) {
+ perror("accept_loop socket:");
+ VERIFY(0);
+ }
+
+ int yes = 1;
+ setsockopt(tcp_, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
+ setsockopt(tcp_, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes));
+
+ // careful to exactly match type signature of bind arguments so we don't
+ // get std::bind instead
+ if (bind(tcp_, (const struct sockaddr *)&sin, (socklen_t)sizeof(sin)) < 0) {
+ perror("accept_loop tcp bind:");
+ VERIFY(0);
+ }
+
+ if (listen(tcp_, 1000) < 0) {
+ perror("listen:");
+ VERIFY(0);
+ }
+
+ socklen_t addrlen = sizeof(sin);
+ VERIFY(getsockname(tcp_, (sockaddr *)&sin, &addrlen) == 0);
+ port_ = ntoh(sin.sin_port);
+
+ IF_LEVEL(2) LOG("listen on " << port_ << " " << sin.sin_port);
+
+ if (pipe(pipe_) < 0) {
+ perror("accept_loop pipe:");
+ VERIFY(0);
+ }
+
+ int flags = fcntl(pipe_[0], F_GETFL, NULL);
+ flags |= O_NONBLOCK;
+ fcntl(pipe_[0], F_SETFL, flags);
+
+ th_ = thread(&tcpsconn::accept_conn, this);