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:
@@ -201,33 +201,7 @@ PIPeer::~PIPeer() {
|
||||
stop();
|
||||
if (destroyed) return;
|
||||
destroyed = true;
|
||||
sync_timer.stopAndWait();
|
||||
diag_s.stopAndWait();
|
||||
diag_d.stopAndWait();
|
||||
PIMutexLocker ml(peers_mutex);
|
||||
piForeach(PeerInfo & p, peers)
|
||||
if (p._data) {
|
||||
p._data->dt_in.stop();
|
||||
p._data->dt_out.stop();
|
||||
p._data->t.stopAndWait();
|
||||
}
|
||||
destroyEths();
|
||||
piForeach(PIEthernet * i, eths_mcast) {
|
||||
if (!i) continue;
|
||||
i->stopAndWait();
|
||||
}
|
||||
piForeach(PIEthernet * i, eths_bcast) {
|
||||
if (!i) continue;
|
||||
i->stopAndWait();
|
||||
}
|
||||
eth_lo.stopAndWait();
|
||||
eth_tcp_srv.stopAndWait();
|
||||
eth_tcp_cli.stopAndWait();
|
||||
sendSelfRemove();
|
||||
destroyMBcasts();
|
||||
eth_send.close();
|
||||
piForeach(PeerInfo & p, peers)
|
||||
p.destroy();
|
||||
destroy();
|
||||
}
|
||||
|
||||
|
||||
@@ -363,6 +337,42 @@ void PIPeer::initMBcasts(PIStringList al) {
|
||||
}
|
||||
|
||||
|
||||
void PIPeer::destroy() {
|
||||
sync_timer.stopAndWait();
|
||||
diag_s.stopAndWait();
|
||||
diag_d.stopAndWait();
|
||||
PIMutexLocker ml(peers_mutex);
|
||||
for (auto & p: peers)
|
||||
if (p._data) {
|
||||
p._data->dt_in.stop();
|
||||
p._data->dt_out.stop();
|
||||
p._data->t.stopAndWait();
|
||||
}
|
||||
destroyEths();
|
||||
for (auto * i: eths_mcast) {
|
||||
if (!i) continue;
|
||||
i->stopAndWait();
|
||||
}
|
||||
for (auto * i: eths_bcast) {
|
||||
if (!i) continue;
|
||||
i->stopAndWait();
|
||||
}
|
||||
eth_lo.stopAndWait();
|
||||
eth_tcp_srv.stopAndWait();
|
||||
eth_tcp_cli.stopAndWait();
|
||||
sendSelfRemove();
|
||||
eth_lo.close();
|
||||
eth_tcp_srv.close();
|
||||
eth_tcp_cli.close();
|
||||
destroyMBcasts();
|
||||
eth_send.close();
|
||||
for (auto & p: peers)
|
||||
p.destroy();
|
||||
peers.clear();
|
||||
destroyed = true;
|
||||
}
|
||||
|
||||
|
||||
void PIPeer::destroyEths() {
|
||||
for (auto * i: eths_traffic) {
|
||||
if (!i) continue;
|
||||
@@ -930,6 +940,7 @@ ssize_t PIPeer::bytesAvailable() const {
|
||||
|
||||
|
||||
ssize_t PIPeer::readDevice(void * read_to, ssize_t max_size) {
|
||||
iterrupted = false;
|
||||
read_buffer_mutex.lock();
|
||||
bool empty = read_buffer.isEmpty();
|
||||
read_buffer_mutex.unlock();
|
||||
@@ -937,6 +948,9 @@ ssize_t PIPeer::readDevice(void * read_to, ssize_t max_size) {
|
||||
read_buffer_mutex.lock();
|
||||
empty = read_buffer.isEmpty();
|
||||
read_buffer_mutex.unlock();
|
||||
if (iterrupted) {
|
||||
return 0;
|
||||
}
|
||||
piMSleep(10);
|
||||
}
|
||||
read_buffer_mutex.lock();
|
||||
@@ -945,6 +959,9 @@ ssize_t PIPeer::readDevice(void * read_to, ssize_t max_size) {
|
||||
read_buffer_mutex.unlock();
|
||||
ssize_t sz = piMini(ba.size_s(), max_size);
|
||||
memcpy(read_to, ba.data(), sz);
|
||||
if (iterrupted) {
|
||||
return 0;
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
read_buffer_mutex.unlock();
|
||||
@@ -964,6 +981,11 @@ ssize_t PIPeer::writeDevice(const void * data, ssize_t size) {
|
||||
}
|
||||
|
||||
|
||||
void PIPeer::interrupt() {
|
||||
iterrupted = true;
|
||||
}
|
||||
|
||||
|
||||
void PIPeer::newTcpClient(PIEthernet * client) {
|
||||
client->setName("__S__PIPeer_eth_TCP_ServerClient" + client->path());
|
||||
piCoutObj << "client" << client->path();
|
||||
|
||||
@@ -171,6 +171,8 @@ protected:
|
||||
EVENT_HANDLER2(bool, dataRead, const uchar *, readed, ssize_t, size);
|
||||
EVENT_HANDLER2(bool, mbcastRead, const uchar *, readed, ssize_t, size);
|
||||
|
||||
void destroy();
|
||||
|
||||
private:
|
||||
EVENT_HANDLER1(void, timerEvent, int, delim);
|
||||
EVENT_HANDLER2(bool, sendInternal, const PIString &, to, const PIByteArray &, data);
|
||||
@@ -212,6 +214,7 @@ private:
|
||||
void configureFromVariantDevice(const PIPropertyStorage & d) override;
|
||||
ssize_t readDevice(void * read_to, ssize_t max_size) override;
|
||||
ssize_t writeDevice(const void * data, ssize_t size) override;
|
||||
void interrupt() override;
|
||||
DeviceInfoFlags deviceInfoFlags() const override { return PIIODevice::Reliable; }
|
||||
|
||||
PeerInfo * quickestPeer(const PIString & to);
|
||||
@@ -243,6 +246,7 @@ private:
|
||||
mutable PIMutex read_buffer_mutex;
|
||||
PIQueue<PIByteArray> read_buffer;
|
||||
int read_buffer_size;
|
||||
std::atomic_bool iterrupted = {false};
|
||||
PIMutex mc_mutex, eth_mutex, peers_mutex, send_mutex, send_mc_mutex;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user