version 4.0.0_alpha

in almost all methods removed timeouts in milliseconds, replaced to PISystemTime
PITimer rewrite, remove internal impl, now only thread implementation, API similar to PIThread
PITimer API no longer pass void*
PIPeer, PIConnection improved stability on reinit and exit
PISystemTime new methods
pisd now exit without hanging
This commit is contained in:
2024-07-30 14:18:02 +03:00
parent f07c9cbce8
commit 1c7fc39b6c
58 changed files with 677 additions and 1191 deletions

View File

@@ -19,6 +19,8 @@
#include "pibasetransfer.h"
#include "pitime.h"
const uint PIBaseTransfer::signature = 0x54424950;
PIBaseTransfer::PIBaseTransfer(): crc(standardCRC_16()), diag(false) {
@@ -33,7 +35,7 @@ PIBaseTransfer::PIBaseTransfer(): crc(standardCRC_16()), diag(false) {
send_queue = 0;
send_up = 0;
timeout_ = 10.;
diag.setDisconnectTimeout(timeout_ / 10);
diag.setDisconnectTimeout(PISystemTime::fromSeconds(timeout_ / 10.));
diag.setName("PIBaseTransfer");
diag.start(50);
packets_count = 10;
@@ -47,7 +49,7 @@ PIBaseTransfer::PIBaseTransfer(): crc(standardCRC_16()), diag(false) {
PIBaseTransfer::~PIBaseTransfer() {
diag.stop();
diag.stopAndWait();
break_ = true;
}
@@ -77,6 +79,12 @@ void PIBaseTransfer::setPause(bool pause_) {
}
void PIBaseTransfer::setTimeout(double sec) {
timeout_ = sec;
diag.setDisconnectTimeout(PISystemTime::fromSeconds(sec));
}
void PIBaseTransfer::received(PIByteArray data) {
packet_header_size = sizeof(PacketHeader) + customHeader().size();
if (data.size() < sizeof(PacketHeader)) {

View File

@@ -65,10 +65,7 @@ public:
void setPacketSize(int size) { packet_size = size; }
int packetSize() const { return packet_size; }
void setTimeout(double sec) {
timeout_ = sec;
diag.setDisconnectTimeout(sec);
}
void setTimeout(double sec);
double timeout() const { return timeout_; }
void setCRCEnabled(bool en = true) { crc_enabled = en; }

View File

@@ -21,6 +21,8 @@
#include "piconfig.h"
#include "piiostream.h"
#include "piliterals_time.h"
#include "pitime.h"
/** \class PIConnection
* \brief Complex Input/Output point
@@ -160,7 +162,9 @@ bool PIConnection::configure(PIConfig & conf, const PIString & name_) {
PIConfig::Entry de = ce.getValue("device." + n);
dev->setThreadedReadBufferSize(de.getValue("bufferSize", dev->threadedReadBufferSize()).toInt());
PIDiagnostics * diag = diags_.value(dev, nullptr);
if (diag) diag->setDisconnectTimeout(de.getValue("disconnectTimeout", diag->disconnectTimeout()).toFloat());
if (diag)
diag->setDisconnectTimeout(
PISystemTime::fromSeconds(de.getValue("disconnectTimeout", diag->disconnectTimeout().toSeconds()).toFloat()));
}
int added(0), padded(-1), tries(0);
bool pdebug = debug();
@@ -223,9 +227,11 @@ bool PIConnection::configure(PIConfig & conf, const PIString & name_) {
}
}
PIDiagnostics * diag = diags_.value(pe, nullptr);
if (diag) diag->setDisconnectTimeout(e->getValue("disconnectTimeout", diag->disconnectTimeout()).toFloat());
if (diag)
diag->setDisconnectTimeout(
PISystemTime::fromSeconds(e->getValue("disconnectTimeout", diag->disconnectTimeout().toSeconds()).toFloat()));
pe->setPayloadSize(e->getValue("payloadSize", pe->payloadSize()).toInt());
pe->setTimeout(e->getValue("timeout", pe->timeout()).toDouble());
pe->setTimeout(PISystemTime::fromMilliseconds(e->getValue("timeout", pe->timeout().toMilliseconds()).toDouble()));
pe->setHeader(PIByteArray::fromUserInput(e->getValue("header", "").toString()));
pe->setFooter(PIByteArray::fromUserInput(e->getValue("footer", "").toString()));
}
@@ -271,7 +277,7 @@ PIString PIConnection::makeConfig() const {
ts << "device." << dname << " = " << d->constructFullPath() << " #s\n";
ts << "device." << dname << ".bufferSize = " << d->threadedReadBufferSize() << " #n\n";
PIDiagnostics * diag = diags_.value(const_cast<PIIODevice *>(d), nullptr);
if (diag) ts << "device." << dname << ".disconnectTimeout = " << diag->disconnectTimeout() << " #f\n";
if (diag) ts << "device." << dname << ".disconnectTimeout = " << diag->disconnectTimeout().toSeconds() << " #f\n";
}
}
auto ite = extractors.makeIterator();
@@ -285,7 +291,7 @@ PIString PIConnection::makeConfig() const {
ts << prefix << ".device." << i << " = " << dname << " #s\n";
}
PIDiagnostics * diag = diags_.value(ite.value()->extractor, nullptr);
if (diag) ts << prefix << ".disconnectTimeout = " << diag->disconnectTimeout() << " #f\n";
if (diag) ts << prefix << ".disconnectTimeout = " << diag->disconnectTimeout().toSeconds() << " #f\n";
ts << prefix << ".splitMode = ";
switch (ite.value()->extractor->splitMode()) {
case PIPacketExtractor::None: ts << "none"; break;
@@ -297,7 +303,7 @@ PIString PIConnection::makeConfig() const {
}
ts << " #s\n";
ts << prefix << ".payloadSize = " << ite.value()->extractor->payloadSize() << " #n\n";
ts << prefix << ".timeout = " << ite.value()->extractor->timeout() << " #f\n";
ts << prefix << ".timeout = " << ite.value()->extractor->timeout().toMilliseconds() << " #f\n";
ts << prefix << ".header = " << ite.value()->extractor->header().toString() << " #s\n";
ts << prefix << ".footer = " << ite.value()->extractor->footer().toString() << " #s\n";
}
@@ -324,8 +330,8 @@ PIString PIConnection::makeConfig() const {
if (dname.isEmpty()) dname = devPath(its.value()->devices[i]);
ts << prefix << ".device." << i << " = " << dname << " #s\n";
}
double int_ = its.value()->int_;
if (int_ > 0.) ts << prefix << ".frequency = " << (1000. / int_) << " #f\n";
auto int_ = its.value()->int_;
if (!int_.isNull()) ts << prefix << ".frequency = " << (1. / int_.toSeconds()) << " #f\n";
if (!its.value()->sdata.isEmpty()) ts << prefix << ".fixedData = " << its.value()->sdata.toString() << " #s\n";
}
ts << "[]\n";
@@ -342,7 +348,7 @@ PIIODevice * PIConnection::addDevice(const PIString & full_path, PIIODevice::Dev
__device_pool__->lock();
if (!diags_.value(dev, nullptr)) {
PIDiagnostics * d = new PIDiagnostics(false);
d->setInterval(100.);
d->setInterval(10_Hz);
diags_[dev] = d;
CONNECT2(void, PIDiagnostics::Quality, PIDiagnostics::Quality, d, qualityChanged, this, diagQualityChanged);
__device_pool__->init();
@@ -476,7 +482,7 @@ PIPacketExtractor * PIConnection::addFilter(const PIString & name_, const PIStri
__device_pool__->lock();
if (!diags_.value(e->extractor, nullptr)) {
PIDiagnostics * d = new PIDiagnostics(false);
d->setInterval(100.);
d->setInterval(10_Hz);
diags_[e->extractor] = d;
CONNECT2(void, PIDiagnostics::Quality, PIDiagnostics::Quality, d, qualityChanged, this, diagQualityChanged);
}
@@ -514,7 +520,7 @@ PIPacketExtractor * PIConnection::addFilter(PIPacketExtractor * filter, const PI
__device_pool__->lock();
if (diags_.value(e->extractor, 0) == 0) {
PIDiagnostics * d = new PIDiagnostics(false);
d->setInterval(100.);
d->setInterval(10_Hz);
diags_[e->extractor] = d;
CONNECT2(void, PIDiagnostics::Quality, PIDiagnostics::Quality, d, qualityChanged, this, diagQualityChanged);
}
@@ -728,7 +734,7 @@ void PIConnection::addSender(const PIString & name_, const PIString & full_path_
if (!s) {
s = new Sender(this);
s->setName(fname_);
s->int_ = 1000. / frequency;
s->int_ = PISystemTime::fromSeconds(1. / frequency);
senders[fname_] = s;
}
PIIODevice * dev = devByString(full_path_name);
@@ -797,9 +803,9 @@ PIByteArray PIConnection::senderFixedData(const PIString & name) const {
float PIConnection::senderFrequency(const PIString & name) const {
Sender * s = senders.value(name, nullptr);
if (!s) return -1.f;
double i = s->interval();
if (i == 0.) return 0.f;
return 1000. / s->interval();
auto i = s->interval();
if (i.isNull()) return 0.f;
return 1. / s->interval().toSeconds();
}
@@ -865,14 +871,14 @@ void PIConnection::stopAllThreadedReads() {
void PIConnection::stopSender(const PIString & name) {
Sender * s = senders.value(name, nullptr);
if (!s) return;
if (s->isRunning()) s->stop();
if (s->isRunning()) s->stopAndWait();
}
void PIConnection::stopAllSenders() {
for (auto s = senders.begin(); s != senders.end(); s++) {
if (!s.value()) continue;
if (s.value()->isRunning()) s.value()->stop();
if (s.value()->isRunning()) s.value()->stopAndWait();
}
}
@@ -949,7 +955,7 @@ bool PIConnection::isFakeMode() {
}
PIConnection::DevicePool::DevicePool(): PIThread(false, 10) {
PIConnection::DevicePool::DevicePool(): PIThread(false, 100_Hz) {
setName("PIConnection::DevicePool");
needLockRun(true);
fake = false;
@@ -960,7 +966,7 @@ PIConnection::DevicePool::~DevicePool() {}
void PIConnection::DevicePool::init() {
if (!isRunning()) start(100);
if (!isRunning()) start(10_Hz);
}
@@ -1111,7 +1117,7 @@ PIConnection::DevicePool::DeviceData::~DeviceData() {
if (rthread) {
rthread->stop();
if (dev) dev->interrupt();
if (!rthread->waitForFinish(1000)) rthread->terminate();
if (!rthread->waitForFinish(1_s)) rthread->terminate();
delete rthread;
rthread = nullptr;
}
@@ -1128,7 +1134,7 @@ void PIConnection::DevicePool::run() {
for (PIConnection * c: conns) {
for (auto d = c->diags_.begin(); d != c->diags_.end(); d++) {
if (!d.value()) continue;
d.value()->tick(0, 1);
d.value()->tick(1);
}
}
}
@@ -1143,9 +1149,9 @@ void __DevicePool_threadReadDP(void * ddp) {
}
if (dev->isClosed()) {
if (!dev->open()) {
auto timeout = dev->reopenTimeout();
PITimeMeasurer tm;
int timeout = dev->reopenTimeout();
while (tm.elapsed_m() < timeout) {
while (tm.elapsed() < timeout) {
if (dd->rthread->isStopping()) return;
piMSleep(50);
}
@@ -1204,13 +1210,13 @@ PIConnection::Extractor::~Extractor() {
}
PIConnection::Sender::Sender(PIConnection * parent_): parent(parent_), int_(0.f) {
PIConnection::Sender::Sender(PIConnection * parent_): parent(parent_) {
setName("__S__.PIConnection.Sender");
needLockRun(true);
}
void PIConnection::Sender::tick(void *, int) {
void PIConnection::Sender::tick(int) {
if (!parent) return;
PIByteArray data;
if (!sdata.isEmpty())

View File

@@ -387,12 +387,12 @@ private:
public:
Sender(PIConnection * parent_ = 0);
~Sender() { stop(); }
~Sender() { stopAndWait(); }
PIConnection * parent;
PIVector<PIIODevice *> devices;
PIByteArray sdata;
float int_;
void tick(void *, int) override;
PISystemTime int_;
void tick(int) override;
};
PIMap<PIString, Extractor *> extractors;

View File

@@ -19,6 +19,8 @@
#include "pidiagnostics.h"
#include "piliterals_time.h"
/** \class PIDiagnostics
* \brief Connection quality diagnostics
@@ -42,18 +44,18 @@ PIDiagnostics::State::State() {
}
PIDiagnostics::PIDiagnostics(bool start_): PITimer(/*PITimer::Pool*/) {
PIDiagnostics::PIDiagnostics(bool start_): PITimer() {
// piCout << "PIDiagnostics construct";
setInterval(100);
setInterval(10_Hz);
reset();
setDisconnectTimeout(3.);
changeDisconnectTimeout(3.);
if (start_) PITimer::start(100);
setDisconnectTimeout(3_s);
changeDisconnectTimeout(3_s);
if (start_) PITimer::start(10_Hz);
// piCout << "PIDiagnostics construct done";
}
PIDiagnostics::~PIDiagnostics() {
PITimer::stop();
PITimer::stopAndWait();
// piCout << "~PIDiagnostics start...";
// piCout << "~PIDiagnostics done!";
}
@@ -92,14 +94,14 @@ PIString PIDiagnostics::sendSpeed() const {
void PIDiagnostics::start() {
PITimer::start(100.);
PITimer::start(10_Hz);
changeDisconnectTimeout(disconn_);
}
void PIDiagnostics::start(double msecs) {
if (msecs > 0.) {
PITimer::start(msecs);
PITimer::start(PISystemTime::fromMilliseconds(msecs));
changeDisconnectTimeout(disconn_);
}
}
@@ -108,7 +110,7 @@ void PIDiagnostics::start(double msecs) {
void PIDiagnostics::reset() {
mutex_state.lock();
cur_state = State();
if (disconn_ != 0.) {
if (disconn_.isNotNull()) {
int hist_size = history_rec.size();
history_rec.clear();
history_send.clear();
@@ -150,16 +152,16 @@ void PIDiagnostics::sended(int size) {
}
void PIDiagnostics::tick(void *, int) {
void PIDiagnostics::tick(int) {
mutex_state.lock();
// piCoutObj << "lock";
int tcnt_recv = 0;
int tcnt_send = 0;
Entry send = calcHistory(history_send, tcnt_send);
Entry recv = calcHistory(history_rec, tcnt_recv);
float itr = disconn_ * (float(tcnt_recv) / history_rec.size());
float its = disconn_ * (float(tcnt_send) / history_send.size());
float hz = interval() / 1000.f;
float itr = disconn_.toSeconds() * (float(tcnt_recv) / history_rec.size());
float its = disconn_.toSeconds() * (float(tcnt_send) / history_send.size());
float hz = 1. / interval().toSeconds();
if (tcnt_recv == 0) {
cur_state.integral_freq = cur_state.immediate_freq = 0;
cur_state.received_packets_per_sec = cur_state.received_bytes_per_sec = 0;
@@ -229,16 +231,15 @@ PIDiagnostics::Entry PIDiagnostics::calcHistory(PIQueue<Entry> & hist, int & cnt
void PIDiagnostics::propertyChanged(const char *) {
float disct = property("disconnectTimeout").toFloat();
changeDisconnectTimeout(disct);
changeDisconnectTimeout(property("disconnectTimeout").toSystemTime());
}
void PIDiagnostics::changeDisconnectTimeout(float disct) {
void PIDiagnostics::changeDisconnectTimeout(PISystemTime disct) {
mutex_state.lock();
disconn_ = piMaxf(disct, interval() / 1000.f);
if (interval() > 0) {
int hist_size = piClampi(int(disconn_ * 1000.f / float(interval())), 1, 65536);
disconn_ = piMax(disct, interval());
if (!interval().isNull()) {
int hist_size = piClampi(piRound(disconn_.toSeconds() / interval().toSeconds()), 1, 65536);
// piCoutObj << hist_size << interval();
history_rec.resize(hist_size);
history_send.resize(hist_size);

View File

@@ -75,13 +75,15 @@ public:
PIDiagnostics::State state() const;
//! Returns period of full disconnect in seconds and period of averaging frequency
float disconnectTimeout() const { return disconn_; }
PISystemTime disconnectTimeout() const { return disconn_; }
//! Returns period of full disconnect in seconds and period of averaging frequency
void setDisconnectTimeout(float s) { setProperty("disconnectTimeout", s); }
void setDisconnectTimeout(float s) DEPRECATEDM("use setDisconnectTimeout(PISystemTime)") {
setDisconnectTimeout(PISystemTime::fromSeconds(s));
}
//! Returns period of full disconnect and period of averaging frequency
void setDisconnectTimeout(PISystemTime tm) { setProperty("disconnectTimeout", tm.toSeconds()); }
void setDisconnectTimeout(PISystemTime tm) { setProperty("disconnectTimeout", tm); }
//! Returns connection quality
PIDiagnostics::Quality quality() const;
@@ -139,13 +141,13 @@ private:
friend bool operator!=(const PIDiagnostics::Entry & f, const PIDiagnostics::Entry & s);
friend bool operator<(const PIDiagnostics::Entry & f, const PIDiagnostics::Entry & s);
void tick(void *, int) override;
void tick(int) override;
Entry calcHistory(PIQueue<Entry> & hist, int & cnt);
void propertyChanged(const char *) override;
void changeDisconnectTimeout(float disct);
void changeDisconnectTimeout(PISystemTime disct);
PIQueue<Entry> history_rec, history_send;
float disconn_ = 0.f;
PISystemTime disconn_;
State cur_state;
mutable PIMutex mutex_state;
};

View File

@@ -97,7 +97,7 @@ void PIPacketExtractor::construct() {
func_footer = nullptr;
func_payload = nullptr;
setPayloadSize(0);
setTimeout(100);
setTimeout(100_ms);
#ifdef MICRO_PIP
setThreadedReadBufferSize(512);
#else
@@ -115,7 +115,7 @@ void PIPacketExtractor::propertyChanged(const char *) {
dataSize = property("payloadSize").toInt();
src_header = property("header").toByteArray();
src_footer = property("footer").toByteArray();
time_ = property("timeout").toDouble();
time_ = property("timeout").toSystemTime();
}

View File

@@ -53,7 +53,7 @@ public:
Footer /** Detect packets with \a footer() and leading \a payloadSize() */,
HeaderAndFooter /** Detect packets with \a header() and \a footer() without \a payloadSize() */,
Size /** Detect packets with \a packetSize() */,
Timeout /** Wait for first read, then read for \a timeout() milliseconds */
Timeout /** Wait for first read, then read for \a timeout() */
};
//! Contructs extractor with child device "device_" and extract algorithm "mode"
@@ -87,8 +87,8 @@ public:
//! Set footer data, used for PIPacketExtractor::Footer and PIPacketExtractor::HeaderAndFooter algorithms
void setFooter(const PIByteArray & data);
//! Set timeout in milliseconds, used for PIPacketExtractor::Timeout algorithm
void setTimeout(double msecs) { setProperty("timeout", msecs); }
//! Set timeout, used for PIPacketExtractor::Timeout algorithm
void setTimeout(PISystemTime tm) { setProperty("timeout", tm); }
//! Returns current extract algorithm
@@ -105,7 +105,7 @@ public:
PIByteArray footer() const { return src_footer; }
//! Returns current timeout in milliseconds, used for PIPacketExtractor::Timeout algorithm
double timeout() const { return time_; }
PISystemTime timeout() const { return time_; }
//! Returns missed by validating functions bytes count
ullong missedBytes() const { return missed; }
@@ -165,7 +165,7 @@ private:
PacketExtractorFooterFunc func_footer;
SplitMode mode_;
int dataSize, packetSize_pending, footerInd;
double time_;
PISystemTime time_;
bool header_found;
ullong missed;
};