server: Fix several crashes with variable iteration
This commit is contained in:
+37
-16
@@ -105,50 +105,68 @@ void datapath::windows::server::_watcher()
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
datapath::error ec = datapath::waitable::wait_any(waits, index, std::chrono::milliseconds(1));
|
datapath::error ec = datapath::waitable::wait_any(waits, index, std::chrono::milliseconds(0));
|
||||||
|
if (ec != datapath::error::Success) {
|
||||||
|
datapath::waitable::wait_any(waits, index, std::chrono::milliseconds(1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update list of overlappeds to track.
|
// Update list of overlappeds to track.
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> ul(this->lock);
|
std::unique_lock<std::mutex> ul(this->lock);
|
||||||
|
std::list<HANDLE> to_kill;
|
||||||
|
|
||||||
for (auto itr = this->waiting_sockets.begin(); itr != this->waiting_sockets.end(); itr++) {
|
for (auto itr = this->waiting_sockets.begin(); itr != this->waiting_sockets.end(); itr++) {
|
||||||
if (ovmap.count(*itr) == 0) {
|
if (ovmap.count(*itr) == 0) {
|
||||||
auto ov = std::make_shared<datapath::windows::overlapped>();
|
HANDLE handle = *itr;
|
||||||
ov->set_handle(*itr);
|
auto ov = std::make_shared<datapath::windows::overlapped>();
|
||||||
|
ov->set_handle(handle);
|
||||||
ov->set_data(this);
|
ov->set_data(this);
|
||||||
ov->on_wait_success.add([this, &ovmap, &itr](datapath::error ec) {
|
ov->on_wait_success.add([this, &ovmap, &itr, &handle](datapath::error ec) {
|
||||||
std::unique_lock<std::mutex> ul(this->lock);
|
std::unique_lock<std::mutex> ul(this->lock);
|
||||||
this->waiting_sockets.remove(*itr);
|
this->waiting_sockets.erase(itr);
|
||||||
this->pending_sockets.push_back(*itr);
|
this->pending_sockets.push_back(handle);
|
||||||
ovmap.erase(*itr);
|
ovmap.erase(handle);
|
||||||
});
|
});
|
||||||
BOOL suc = ConnectNamedPipe(*itr, ov->get_overlapped());
|
SetLastError(ERROR_SUCCESS);
|
||||||
|
BOOL suc = ConnectNamedPipe(handle, ov->get_overlapped());
|
||||||
if (suc) {
|
if (suc) {
|
||||||
ovmap.insert({*itr, ov});
|
ovmap.insert({handle, ov});
|
||||||
} else {
|
} else {
|
||||||
continue;
|
if (GetLastError() == ERROR_PIPE_CONNECTED) {
|
||||||
|
to_kill.push_back(handle);
|
||||||
|
this->pending_sockets.push_back(handle);
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (auto hnd : to_kill) {
|
||||||
|
this->waiting_sockets.remove(hnd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify of pending sockets.
|
// Notify of pending sockets.
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> ul(this->lock);
|
std::unique_lock<std::mutex> ul(this->lock);
|
||||||
|
std::list<HANDLE> to_kill;
|
||||||
|
|
||||||
if (this->on_accept) {
|
if (this->on_accept) {
|
||||||
for (auto itr = this->pending_sockets.begin(); itr != this->pending_sockets.end();
|
for (auto itr = this->pending_sockets.begin(); itr != this->pending_sockets.end();
|
||||||
itr++) {
|
itr++) {
|
||||||
bool accept = true;
|
HANDLE handle = *itr;
|
||||||
|
bool accept = true;
|
||||||
|
|
||||||
auto sock = std::make_shared<datapath::windows::socket>();
|
auto sock = std::make_shared<datapath::windows::socket>();
|
||||||
sock->_connect(*itr);
|
sock->_connect(handle);
|
||||||
|
|
||||||
auto isock = std::dynamic_pointer_cast<datapath::isocket>(sock);
|
auto isock = std::dynamic_pointer_cast<datapath::isocket>(sock);
|
||||||
this->on_accept(accept, isock);
|
this->on_accept(accept, isock);
|
||||||
|
|
||||||
if (accept) {
|
if (accept) {
|
||||||
this->pending_sockets.erase(itr);
|
to_kill.push_back(handle);
|
||||||
this->active_sockets.insert({*itr, sock});
|
this->active_sockets.insert({handle, sock});
|
||||||
|
|
||||||
if ((this->waiting_sockets.size() + this->pending_sockets.size())
|
if ((this->waiting_sockets.size() + this->pending_sockets.size())
|
||||||
< WIN_BACKLOG_NUM) {
|
< WIN_BACKLOG_NUM) {
|
||||||
@@ -164,11 +182,14 @@ void datapath::windows::server::_watcher()
|
|||||||
} else {
|
} else {
|
||||||
// Force close and return to waiting.
|
// Force close and return to waiting.
|
||||||
sock->close();
|
sock->close();
|
||||||
this->pending_sockets.erase(itr);
|
to_kill.push_back(handle);
|
||||||
this->waiting_sockets.push_back(*itr);
|
this->waiting_sockets.push_back(handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (auto hnd : to_kill) {
|
||||||
|
this->pending_sockets.remove(hnd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify existing connections.
|
// Verify existing connections.
|
||||||
|
|||||||
Reference in New Issue
Block a user