PIIODevice threaded read refactoring

This commit is contained in:
2022-10-23 16:02:09 +03:00
parent e5777dde6c
commit 9438ab4e53
9 changed files with 157 additions and 121 deletions

View File

@@ -116,14 +116,14 @@ PIMutex PIIODevice::nfp_mutex;
PIMap<PIString, PIString> PIIODevice::nfp_cache;
PIIODevice::PIIODevice(): PIThread() {
PIIODevice::PIIODevice(): PIObject() {
mode_ = ReadOnly;
_init();
setPath(PIString());
}
PIIODevice::PIIODevice(const PIString & path, PIIODevice::DeviceMode mode): PIThread() {
PIIODevice::PIIODevice(const PIString & path, PIIODevice::DeviceMode mode): PIObject() {
mode_ = mode;
_init();
setPath(path);
@@ -149,6 +149,18 @@ bool PIIODevice::setOption(PIIODevice::DeviceOption o, bool yes) {
}
void PIIODevice::setReopenEnabled(bool yes) {
setProperty("reopenEnabled", yes);
reopen_enabled = yes;
}
void PIIODevice::setReopenTimeout(int msecs) {
setProperty("reopenTimeout", msecs);
reopen_timeout = msecs;
}
//! \~\details
//! \~english
//! Set external static function of threaded read that will be executed
@@ -177,34 +189,72 @@ void PIIODevice::setThreadedReadBufferSize(int new_size) {
}
bool stopThread(PIThread * t, bool hard) {
bool PIIODevice::isThreadedRead() const {
return read_thread.isRunning();
}
void PIIODevice::startThreadedRead() {
if (!read_thread.isRunning()) {
buffer_tr.resize(threaded_read_buffer_size);
read_thread.start();
}
}
void PIIODevice::startThreadedRead(ReadRetFunc func) {
func_read = func;
startThreadedRead();
}
void PIIODevice::stopThreadedRead() {
if (!isThreadedRead()) return;
#ifdef MICRO_PIP
t->stop(true);
read_thread.stop(true);
#else
if (hard) {
t->terminate();
return true;
if (reading_now) {
read_thread.terminate();
reading_now = false;
} else {
t->stop();
if (!t->waitForFinish(10000)) {
t->terminate();
return true;
}
read_thread.stop();
}
#endif
return false;
}
void PIIODevice::stopThreadedRead(bool hard) {
if (stopThread(this, hard))
threadedReadTerminated();
bool PIIODevice::waitThreadedReadFinished(int timeout_ms) {
return read_thread.waitForFinish(timeout_ms);
}
void PIIODevice::stopThreadedWrite(bool hard) {
if (stopThread(&write_thread, hard))
bool PIIODevice::isThreadedWrite() const {
return write_thread.isRunning();
}
void PIIODevice::startThreadedWrite() {
if (!write_thread.isRunning())
write_thread.startOnce();
}
void PIIODevice::stopThreadedWrite() {
if (!write_thread.isRunning()) return;
#ifdef MICRO_PIP
write_thread.stop(true);
#else
write_thread.stop();
if (!write_thread.waitForFinish(100)) {
write_thread.terminate();
threadedWriteTerminated();
}
#endif
}
bool PIIODevice::waitThreadedWriteFinished(int timeout_ms) {
return write_thread.waitForFinish(timeout_ms);
}
@@ -221,16 +271,31 @@ void PIIODevice::start() {
}
void PIIODevice::stop(bool hard) {
stopThreadedRead(hard);
stopThreadedWrite(hard);
void PIIODevice::stop() {
stopThreadedRead();
stopThreadedWrite();
}
ssize_t PIIODevice::read(void * read_to, ssize_t max_size) {
reading_now = true;
ssize_t ret = readDevice(read_to, max_size);
reading_now = false;
return ret;
}
ssize_t PIIODevice::read(PIMemoryBlock mb) {
return read(mb.data(), mb.size());
}
PIByteArray PIIODevice::read(ssize_t max_size) {
if (max_size <= 0) return PIByteArray();
buffer_in.resize(max_size);
reading_now = true;
ssize_t ret = readDevice(buffer_in.data(), max_size);
reading_now = false;
if (ret < 0) return PIByteArray();
return buffer_in.resized(ret);
}
@@ -243,6 +308,7 @@ ssize_t PIIODevice::write(const void * data, ssize_t max_size) {
void PIIODevice::_init() {
reading_now = false;
opened_ = init_ = thread_started_ = false;
raise_threaded_read_ = true;
func_read = nullptr;
@@ -257,19 +323,10 @@ void PIIODevice::_init() {
#else
threaded_read_buffer_size = 4096;
#endif
timer.setName("__S__.PIIODevice.reopen_timer");
read_thread .setName("__S__.PIIODevice.read_thread" );
write_thread.setName("__S__.PIIODevice.write_thread");
CONNECT2(void, void * , int, &timer, tickEvent, this, check_start);
CONNECT(void, &write_thread, started, this, write_func);
}
void PIIODevice::check_start(void * data, int delim) {
//cout << "check " << tread_started_ << endl;
if (open()) {
thread_started_ = true;
timer.stop(false);
}
read_thread.setSlot([this](void*){read_func();});
}
@@ -297,52 +354,21 @@ PIIODevice * PIIODevice::newDeviceByPrefix(const char * prefix) {
}
void PIIODevice::terminate() {
timer.stop();
thread_started_ = false;
if (!init_) return;
if (isRunning()) {
#ifdef MICRO_PIP
stop(true);
#else
stop();
PIThread::terminate();
#endif
}
}
void PIIODevice::begin() {
//cout << " begin\n";
buffer_tr.resize(threaded_read_buffer_size);
if (threaded_read_buffer_size == 0)
piCoutObj << "Warning: threadedReadBufferSize() == 0, read may be useless!";
thread_started_ = false;
if (!opened_) {
if (open()) {
thread_started_ = true;
//cout << " open && ok\n";
return;
}
} else {
thread_started_ = true;
//cout << " ok\n";
return;
}
if (!timer.isRunning() && isReopenEnabled()) timer.start(reopenTimeout());
}
void PIIODevice::run() {
void PIIODevice::read_func() {
if (!isReadable()) {
//cout << "not readable\n";
PIThread::stop();
read_thread.stop();
return;
}
if (!thread_started_) {
if (!isOpened()) {
piMSleep(10);
//cout << "not started\n";
return;
bool ok = false;
if (reopen_enabled) {
if (reopen_tm.elapsed_m() >= reopen_timeout) {
reopen_tm.reset();
ok = open();
}
}
if (!ok) return;
}
readed_ = read(buffer_tr.data(), buffer_tr.size_s());
if (readed_ <= 0) {
@@ -415,6 +441,7 @@ bool PIIODevice::close() {
return !opened_;
}
ssize_t PIIODevice::write(PIByteArray data) {
return writeDevice(data.data(), data.size_s());
}
@@ -620,3 +647,8 @@ void PIIODevice::configureFromVariantDevice(const PIPropertyStorage & d) {
setPath(d.propertyValueByName("path").toString());
}
void PIIODevice::softStopThreadedRead() {
read_thread.stop();
}