version 2.8.0

new PIObject::deleteLater method
decompose piobject.h to 2 files
This commit is contained in:
2020-09-18 14:59:24 +03:00
parent 5f7c58c28e
commit 51c7355af4
5 changed files with 701 additions and 446 deletions

View File

@@ -19,6 +19,8 @@
#include "piobject.h"
#include "pisysteminfo.h"
#include "pithread.h"
#include "piconditionvar.h"
#ifndef FREERTOS
# include "pifile.h"
#endif
@@ -73,6 +75,7 @@ PIString PIObject::__MetaFunc::fullFormat() const {
PIObject::PIObject(const PIString & name): _signature_(__PIOBJECT_SIGNATURE__), emitter_(0), thread_safe_(false), proc_event_queue(false) {
in_event_cnt = 0;
setName(name);
setDebug(true);
mutexObjects().lock();
@@ -83,6 +86,7 @@ PIObject::PIObject(const PIString & name): _signature_(__PIOBJECT_SIGNATURE__),
PIObject::~PIObject() {
in_event_cnt = 0;
//piCout << "delete" << this;
mutexObjects().lock();
objects().removeAll(this);
@@ -488,6 +492,11 @@ void PIObject::callQueuedEvents() {
}
void PIObject::deleteLater() {
Deleter::instance()->post(this);
}
bool PIObject::findSuitableMethodV(const PIString & method, int args, int & ret_args, PIObject::__MetaFunc & ret) {
PIVector<__MetaFunc> ml = findEH(method);
if (ml.isEmpty()) {
@@ -674,3 +683,103 @@ void PIObject::__Connection::destroy() {
if (functor) delete functor;
functor = nullptr;
}
PRIVATE_DEFINITION_START(PIObject::Deleter)
PIThread thread;
PIConditionVariable cond_var;
PIMutex cond_mutex, queue_mutex;
PIVector<PIObject*> obj_queue;
PRIVATE_DEFINITION_END(PIObject::Deleter)
PIObject::Deleter::Deleter() {
//piCout << "Deleter start ...";
stopping = started = posted = false;
CONNECTL(&(PRIVATE->thread), started, [this](){proc();});
PRIVATE->thread.startOnce();
while (!started)
piMSleep(1);
}
PIObject::Deleter::~Deleter() {
//piCout << "~Deleter ...";
stopping = true;
PRIVATE->cond_var.notifyAll();
#ifndef WINDOWS
while (PRIVATE->thread.isRunning())
piMSleep(1);
#endif
deleteAll();
//piCout << "~Deleter ok";
}
PIObject::Deleter * PIObject::Deleter::instance() {
static Deleter ret;
return &ret;
}
void PIObject::Deleter::post(PIObject * o) {
if (!o->isPIObject()) return;
//piCout << "[Deleter] post" << o << "...";
PRIVATE->queue_mutex.lock();
if (!PRIVATE->obj_queue.contains(o))
PRIVATE->obj_queue << o;
PRIVATE->queue_mutex.unlock();
PRIVATE->cond_var.notifyAll();
posted = true;
//piCout << "[Deleter] post" << o << "done";
}
void PIObject::Deleter::proc() {
//piCout << "[Deleter] proc start";
while (!stopping) {
//piMSleep(1);
//piCout << "[Deleter] proc wait ...";
if (posted) {
posted = false;
started = true;
} else {
PRIVATE->cond_mutex.lock();
started = true;
PRIVATE->cond_var.wait(PRIVATE->cond_mutex);
PRIVATE->cond_mutex.unlock();
}
//piCout << "[Deleter] proc wait done";
deleteAll();
}
//piCout << "[Deleter] proc end ok";
}
void PIObject::Deleter::deleteAll() {
PIVector<PIObject*> oq;
PRIVATE->queue_mutex.lock();
oq = PRIVATE->obj_queue;
//piCout << "[Deleter] deleteAll" << oq.size_s() << "...";
PRIVATE->obj_queue.clear();
PRIVATE->queue_mutex.unlock();
piForeach (PIObject * o, oq)
deleteObject(o);
}
void PIObject::Deleter::deleteObject(PIObject * o) {
//piCout << "[Deleter] delete" << (uintptr_t)o << "...";
if (o->isPIObject()) {
//piCout << "[Deleter] delete" << (uintptr_t)o << "wait atomic ...";
while (o->isInEvent()) {
piMSleep(1);
}
//piCout << "[Deleter] delete" << (uintptr_t)o << "wait atomic done";
if (o->isPIObject())
delete o;
}
//piCout << "[Deleter] delete" << (uintptr_t)o << "done";
}