google / google/cppdap

Server::start deadlocks on bind failure.

Đang mở
#134 0 bình luận 1 reaction 0 người được giao Xem trên GitHub
Ngôn ngữ chính
C++
Star
192
Fork
66
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Mô tả

It's possible I'm doing something wrong, but I've run into an issue when calling Server::start with an in-use port. A similar issue was reported in #80, but the author closed the ticket without comment.

If you call `Server::start` and bind fails (say a port is already in use), the `start` call never returns. The dead lock happens in the Shared::lock call, which calls shared.reset on failure.

```cpp
// socket.cpp:233
Socket::Socket(const char* address, const char* port)
: shared(Shared::create(address, port)) {
if (shared) {
shared->lock([&](SOCKET socket, const addrinfo* info) {
if (bind(socket, info->ai_addr, (int)info->ai_addrlen) != 0) {
shared.reset(); // Deadlock occurs here.
return;
}

if (listen(socket, 0) != 0) {
shared.reset();
return;
}
});
}
}
```

The Shared::lock method takes a reader lock before calling the function:
```cpp
// socket.cpp:126
template
void lock(FUNCTION&& f) {
RLock l(mutex);
f(s, info);
}
```

The Shared destructor calls close, which at the end attempts to take a writer lock:
```cpp
// socket.cpp:194, bottom of ::close method.
WLock l(mutex);
if (s != InvalidSocket) {
#if !defined(_WIN32) && !defined(__APPLE__)
::close(s);
#endif
s = InvalidSocket;
}
```

That writer lock is waiting for the read lock that is being held by the function calling it, leading to the deadlock.

Am I doing something wrong here? I can work around the issue by trying to bind the socket myself before invoking cppdap and verifying that it works before calling start, but that doesn't seem ideal. The calls to `shared.reset()` inside a call to `shared` seem suspicious to me, but I might well be misreading the code.

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.