PIThreadNotifier, rewrite PIObject::deleteLater()

tests for PIThreadNotifier and PIObject::deleteLater()
This commit is contained in:
Andrey
2021-10-29 18:20:48 +03:00
parent 6e5a5a6ade
commit 48c885e12a
9 changed files with 196 additions and 75 deletions

View File

@@ -698,28 +698,30 @@ bool PIObject::Connection::disconnect() {
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(PIP_MIN_MSLEEP);
PRIVATE->thread.setSlot([this](){
PIVector<PIObject*> oq;
PRIVATE->thread.lock();
while(PRIVATE->obj_queue.isEmpty()) PRIVATE->cond_var.wait(PRIVATE->thread.mutex());
oq.swap(PRIVATE->obj_queue);
PRIVATE->thread.unlock();
for (PIObject * o : oq) deleteObject(o);
});
PRIVATE->thread.start();
}
PIObject::Deleter::~Deleter() {
//piCout << "~Deleter ...";
stopping = true;
PRIVATE->thread.stop();
PRIVATE->cond_var.notifyAll();
#ifndef WINDOWS
while (PRIVATE->thread.isRunning()) piMSleep(PIP_MIN_MSLEEP);
#endif
deleteAll();
PRIVATE->thread.waitForFinish();
for (PIObject * o : PRIVATE->obj_queue) deleteObject(o);
//piCout << "~Deleter ok";
}
@@ -733,46 +735,13 @@ PIObject::Deleter * PIObject::Deleter::instance() {
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->thread.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();
PRIVATE->cond_var.notifyAll();
}
//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);
PRIVATE->thread.unlock();
//piCout << "[Deleter] post" << o << "done";
}
@@ -782,7 +751,7 @@ void PIObject::Deleter::deleteObject(PIObject * o) {
//piCout << "[Deleter] delete" << (uintptr_t)o << "wait atomic ...";
while (o->isInEvent()) piMSleep(PIP_MIN_MSLEEP);
//piCout << "[Deleter] delete" << (uintptr_t)o << "wait atomic done";
if (o->isPIObject()) delete o;
delete o;
}
//piCout << "[Deleter] delete" << (uintptr_t)o << "done";
}