PIIODevice threaded read refactoring
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user