diff --git a/libs/cloud/picloudserver.cpp b/libs/cloud/picloudserver.cpp index f5a54766..38cda7cd 100644 --- a/libs/cloud/picloudserver.cpp +++ b/libs/cloud/picloudserver.cpp @@ -36,9 +36,14 @@ PICloudServer::PICloudServer(const PIString & path, PIIODevice::DeviceMode mode) CONNECTL(ð, disconnected, [this](bool){ if (is_deleted) return; //piCoutObj << "disconnected" << ð + clients_mutex.lock(); + removed_clients_.append(clients_); for (auto c : clients_) { - delete c; + c->is_connected = false; + c->close(); } + clients_.clear(); + clients_mutex.unlock(); opened_ = false; ping_timer.stop(); piMSleep(100); @@ -54,8 +59,12 @@ PICloudServer::~PICloudServer() { is_deleted = true; stop(); close(); - //piCout << "wait"; waitThreadedReadFinished(); + //piCout << "wait"; + for (auto c : removed_clients_) { + delete c; + } + removed_clients_.clear(); //piCoutObj << "~PICloudServer done" << this; } @@ -92,10 +101,11 @@ bool PICloudServer::closeDevice() { eth.stopAndWait(); ping_timer.stop(); eth.close(); - for (auto c : clients_) { - delete c; - } + clients_mutex.lock(); + removed_clients_.append(clients_); clients_.clear(); + index_clients.clear(); + clients_mutex.unlock(); return true; } @@ -233,12 +243,15 @@ void PICloudServer::_readed(PIByteArray & ba) { uint id = tcp.parseDisconnect(ba); //piCoutObj << "remove Client" << id; clients_mutex.lock(); - Client * oc = index_clients.value(id, nullptr); + Client * oc = index_clients.take(id, nullptr); + clients_.removeOne(oc); clients_mutex.unlock(); if (oc) { oc->stopAndWait(); oc->is_connected = false; - delete oc; + oc->close(); + removed_clients_ << oc; + //delete oc; } } break; case PICloud::TCP::Data: { @@ -260,6 +273,7 @@ void PICloudServer::clientDeleted(PIObject * o) { //piCoutObj << "clientDeleted" << c; clients_mutex.lock(); clients_.removeOne(c); + removed_clients_.removeAll(c); auto it = index_clients.makeIterator(); while (it.next()) { if (it.value() == c) { diff --git a/libs/main/cloud/picloudserver.h b/libs/main/cloud/picloudserver.h index 59f8509e..23062329 100644 --- a/libs/main/cloud/picloudserver.h +++ b/libs/main/cloud/picloudserver.h @@ -83,6 +83,7 @@ private: int sendData(const PIByteArray & data, uint client_id); PIVector clients_; + PIVector removed_clients_; PIMap index_clients; PITimer ping_timer; mutable PIMutex clients_mutex; diff --git a/libs/main/containers/pimap.h b/libs/main/containers/pimap.h index 13b60b08..174fd6ac 100644 --- a/libs/main/containers/pimap.h +++ b/libs/main/containers/pimap.h @@ -315,10 +315,10 @@ public: //! \~english Remove element with key `key` from the array and return it. //! \~russian Удаляет элемент с ключом `key` из массива и возвращает его. - inline T take(const Key & key) const { + inline T take(const Key & key, const T & default_ = T()) { bool f(false); ssize_t i = _find(key, f); - if (!f) return T(); + if (!f) return default_; T ret(pim_content[pim_index[i].index]); _remove(i); return ret; diff --git a/libs/main/thread/pithreadnotifier.cpp b/libs/main/thread/pithreadnotifier.cpp index 9eb1aba1..55f65e15 100644 --- a/libs/main/thread/pithreadnotifier.cpp +++ b/libs/main/thread/pithreadnotifier.cpp @@ -122,7 +122,7 @@ void PIThreadNotifier::wait() { //! \~russian //! Если ожидают несколько потоков, то уведомляет один случайный.\n //! Если вызвать "n" раз, то все ожидающие потоки уведомятся суммарно "n" раз. -void PIThreadNotifier::notifyOnce() { +void PIThreadNotifier::notify() { m.lock(); cnt++; v.notifyAll(); diff --git a/libs/main/thread/pithreadnotifier.h b/libs/main/thread/pithreadnotifier.h index e2045a9d..70784899 100644 --- a/libs/main/thread/pithreadnotifier.h +++ b/libs/main/thread/pithreadnotifier.h @@ -39,7 +39,7 @@ public: //! \~english Notify one waiting thread, which waiting on \a wait() function //! \~russian Уведомить один из ожидающих потоков, которые висят на методе \a wait() - void notifyOnce(); + void notify(); private: ullong cnt; diff --git a/main_picloud_test.cpp b/main_picloud_test.cpp index 54171b88..be0a6ca5 100644 --- a/main_picloud_test.cpp +++ b/main_picloud_test.cpp @@ -55,6 +55,7 @@ int main(int argc, char * argv[]) { cl->stop(); clients->removeAll(cl); piCout << "[Server] client closed ok" << cl; + //cl->deleteLater(); })); cl->startThreadedRead(); }));