| 124 | } |
| 125 | |
| 126 | void Acceptor::StopAccept(int /*closewait_ms*/) { |
| 127 | // Currently `closewait_ms' is useless since we have to wait until |
| 128 | // existing requests are finished. Otherwise, contexts depended by |
| 129 | // the requests may be deleted and invalid. |
| 130 | |
| 131 | { |
| 132 | BAIDU_SCOPED_LOCK(_map_mutex); |
| 133 | if (_status != RUNNING) { |
| 134 | return; |
| 135 | } |
| 136 | _status = STOPPING; |
| 137 | } |
| 138 | |
| 139 | // Don't set _acception_id to 0 because BeforeRecycle needs it. |
| 140 | Socket::SetFailed(_acception_id); |
| 141 | |
| 142 | // SetFailed all existing connections. Connections added after this piece |
| 143 | // of code will be SetFailed directly in OnNewConnectionsUntilEAGAIN |
| 144 | std::vector<SocketId> erasing_ids; |
| 145 | ListConnections(&erasing_ids); |
| 146 | |
| 147 | for (size_t i = 0; i < erasing_ids.size(); ++i) { |
| 148 | SocketUniquePtr socket; |
| 149 | if (Socket::Address(erasing_ids[i], &socket) == 0) { |
| 150 | if (socket->shall_fail_me_at_server_stop()) { |
| 151 | // Mainly streaming connections, should be SetFailed() to |
| 152 | // trigger callbacks to NotifyOnFailed() to remove references, |
| 153 | // otherwise the sockets are often referenced by corresponding |
| 154 | // objects and delay server's stopping which requires all |
| 155 | // existing sockets to be recycled. |
| 156 | socket->SetFailed(ELOGOFF, "Server is stopping"); |
| 157 | } else { |
| 158 | // Message-oriented RPC connections. Just release the addtional |
| 159 | // reference in the socket, which will be recycled when current |
| 160 | // requests have been processed. |
| 161 | socket->ReleaseAdditionalReference(); |
| 162 | } |
| 163 | } // else: This socket already called `SetFailed' before |
| 164 | } |
| 165 | } |
| 166 | |
| 167 | int Acceptor::Initialize() { |
| 168 | if (_socket_map.init(INITIAL_CONNECTION_CAP) != 0) { |