important:

* PIThread::~PIThread() now unregister itself from introspection, if terminates than show warning
 * PISystemMonitor now correctly stops
 * PIPeer now can correctly stopAndWait
 * PIPeer::destroy(), protected method for close all eths and threads
 * new PIINTROSPECTION_STOP macro
 * Introspection now can be correctly stopped by macro, more safety

ClientServer:
 * ClientBase::close() stop and disconnect channel
 * Server clients clean-up now event-based
 * No warnings on client destructor
This commit is contained in:
2024-09-12 17:07:48 +03:00
parent da4b09be9e
commit 996b7ea403
17 changed files with 189 additions and 99 deletions

View File

@@ -18,13 +18,15 @@
#include "piclientserver_client.h"
#include "piclientserver_server.h"
#include "piethernet.h"
void PIClientServer::ServerClient::createForServer(PIEthernet * tcp_) {
void PIClientServer::ServerClient::createForServer(Server * parent, PIEthernet * tcp_) {
tcp = tcp_;
tcp->setParameter(PIEthernet::KeepConnection, false);
init();
CONNECTL(tcp, disconnected, ([this, parent](bool) { parent->clientDisconnected(this); }));
}
@@ -37,13 +39,14 @@ PIClientServer::Client::Client() {
PIClientServer::Client::~Client() {
stop();
if (tcp) tcp->setDebug(false);
close();
}
void PIClientServer::Client::connect(PINetworkAddress addr) {
if (!tcp || !own_tcp) return;
stop();
close();
tcp->connect(addr, true);
tcp->startThreadedRead();
piCout << "Connect to" << addr.toString();

View File

@@ -26,17 +26,18 @@ PIClientServer::ClientBase::ClientBase() {}
PIClientServer::ClientBase::~ClientBase() {
stop();
close();
if (own_tcp) piDeleteSafety(tcp);
}
void PIClientServer::ClientBase::stop() {
void PIClientServer::ClientBase::close() {
if (!tcp) return;
can_write = false;
tcp->interrupt();
tcp->stopAndWait(10_s);
if (tcp->isThreadedRead()) tcp->terminateThreadedRead();
tcp->close();
stream.clear();
}

View File

@@ -39,36 +39,37 @@ PIClientServer::Server::Server() {
piCout << "ClientFactory returns nullptr!";
return;
}
sc->createForServer(c);
sc->createForServer(this, c);
newClient(sc);
});
clean_thread->start(
[this]() {
PIVector<ServerClient *> to_delete;
clients_mutex.lock();
for (auto c: clients) {
const PIEthernet * eth = c->getTCP();
if (!eth) continue;
if (eth->isConnected()) continue;
c->can_write = false;
to_delete << c;
}
for (auto c: to_delete)
clients.removeOne(c);
clients_mutex.unlock();
for (auto c: to_delete) {
c->aboutDelete();
c->destroy();
delete c;
}
},
5_Hz);
clean_thread->start([this]() {
clean_notifier.wait();
PIVector<ServerClient *> to_delete;
clients_mutex.lock();
for (auto c: clients) {
const PIEthernet * eth = c->getTCP();
if (!eth) continue;
if (eth->isConnected()) continue;
c->can_write = false;
to_delete << c;
}
for (auto c: to_delete)
clients.removeOne(c);
clients_mutex.unlock();
for (auto c: to_delete) {
c->aboutDelete();
c->destroy();
delete c;
}
});
}
PIClientServer::Server::~Server() {
clean_thread->stopAndWait();
clean_thread->stop();
clean_notifier.notify();
clean_thread->waitForFinish();
piDeleteSafety(clean_thread);
stopServer();
for (auto c: clients) {
@@ -129,3 +130,8 @@ void PIClientServer::Server::newClient(ServerClient * c) {
c->connected();
piCout << "New client";
}
void PIClientServer::Server::clientDisconnected(ServerClient * c) {
clean_notifier.notify();
}