diff --git a/flashmqtestclient.cpp b/flashmqtestclient.cpp index 438bd860..bfb67258 100644 --- a/flashmqtestclient.cpp +++ b/flashmqtestclient.cpp @@ -126,7 +126,12 @@ void FlashMQTestClient::connectClient(ProtocolVersion protocolVersion, bool clea this->client = std::make_shared(sockfd, testServerWorkerThreadData, nullptr, false, false, reinterpret_cast(&servaddr), settings); this->client->setClientProperties(protocolVersion, clientid, "user", false, 60); - testServerWorkerThreadData->giveClient(this->client); + { + // Hack to make it work with the rvalue argument. Because our test client retains ownership of 'client', we can get away + // with this. See git what caused this change. + std::shared_ptr dummyToMoveFrom = this->client; + testServerWorkerThreadData->giveClient(std::move(dummyToMoveFrom)); + } // This gets called in the test client's worker thread, but the STL container's minimal thread safety should be enough: only list manipulation is // mutexed, elements within are not. diff --git a/mainapp.cpp b/mainapp.cpp index fc1a60cc..17a41c1e 100644 --- a/mainapp.cpp +++ b/mainapp.cpp @@ -667,7 +667,7 @@ void MainApp::start() std::shared_ptr client = std::make_shared(fd, thread_data, clientSSL, listener->websocket, listener->isHaProxy(), addr, settings); - thread_data->giveClient(client); + thread_data->giveClient(std::move(client)); globalStats->socketConnects.inc(); } diff --git a/threaddata.cpp b/threaddata.cpp index 32be492a..131aae1d 100644 --- a/threaddata.cpp +++ b/threaddata.cpp @@ -425,17 +425,17 @@ void ThreadData::removeQueuedClients() } } -void ThreadData::giveClient(std::shared_ptr client) +void ThreadData::giveClient(std::shared_ptr &&client) { const int fd = client->getFd(); + queueClientNextKeepAliveCheckLocked(client, false); + { std::lock_guard locker(clients_by_fd_mutex); - clients_by_fd[fd] = client; + clients_by_fd[fd] = std::move(client); // We must give up ownership here, to avoid calling the client destructor in the main thread. } - queueClientNextKeepAliveCheckLocked(client, false); - struct epoll_event ev; memset(&ev, 0, sizeof (struct epoll_event)); ev.data.fd = fd; diff --git a/threaddata.h b/threaddata.h index 2c7d9f83..1d729778 100644 --- a/threaddata.h +++ b/threaddata.h @@ -111,7 +111,7 @@ class ThreadData void start(thread_f f); - void giveClient(std::shared_ptr client); + void giveClient(std::shared_ptr &&client); std::shared_ptr getClient(int fd); void removeClientQueued(const std::shared_ptr &client); void removeClientQueued(int fd);