Skip to content
This repository has been archived by the owner on Sep 4, 2021. It is now read-only.

Commit

Permalink
added function to register actor to be deleted when app exits
Browse files Browse the repository at this point in the history
Signed-off-by: Denis Zalevskiy <denis.zalevskiy@jolla.com>
  • Loading branch information
Denis Zalevskiy committed Jan 12, 2015
1 parent 187e04f commit de79566
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 9 deletions.
4 changes: 3 additions & 1 deletion include/qtaround/mt.hpp
Expand Up @@ -41,9 +41,10 @@ class Actor : public QObject
bool postEvent(QEvent *);
bool sendEvent(QEvent *);
void quit();
bool quitSync(unsigned long timeout);

signals:
void finished();
void finished(Actor*);

private:
friend class ActorImpl;
Expand Down Expand Up @@ -74,6 +75,7 @@ ActorHandle startActorSync
return Actor::createSync(qobj_ctor, parent);
}

void deleteOnApplicationExit(ActorHandle);
}}

#endif // _QTAROUND_MT_HPP_
90 changes: 82 additions & 8 deletions src/mt.cpp
Expand Up @@ -49,6 +49,8 @@ class ActorImpl : public QThread
bool postEvent(QEvent *);
bool sendEvent(QEvent *);

bool quitSync(unsigned long timeout);

private:
std::shared_ptr<QObject> obj_;
};
Expand All @@ -57,16 +59,21 @@ Actor::Actor(QObject *parent)
: QObject(parent), impl_(new ActorImpl(this))
{
connect(impl_, &QThread::finished
, this, &Actor::finished
, Qt::DirectConnection);
, [this]() { this->finished(this); });
}

Actor::~Actor()
{}

void Actor::quit()
{
impl_->quit();
if (impl_->isRunning())
impl_->quit();
}

bool Actor::quitSync(unsigned long timeout)
{
return impl_->quitSync(timeout);
}

void Actor::create(qobj_ctor_type ctor, actor_callback_type cb, QObject *parent)
Expand All @@ -93,11 +100,7 @@ ActorImpl::~ActorImpl()
{
auto app = QCoreApplication::instance();
if (app) {
if (isRunning())
quit();
if (QThread::currentThread() != this)
if (!wait(10000))
debug::warning("Timeout: no quit from thread!");
quitSync(10000);
}
if (obj_ && this != QThread::currentThread())
debug::warning("Managed object is not deleted in a right thread Current:"
Expand Down Expand Up @@ -137,6 +140,20 @@ bool ActorImpl::sendEvent(QEvent *e)
}
}

bool ActorImpl::quitSync(unsigned long timeout)
{
if (!isRunning())
return true;

quit();
if (this != QThread::currentThread())
if (!wait(timeout)) {
debug::warning("Timeout on sync quit");
return false;
}
return true;
}

void ActorImpl::create(qobj_ctor_type ctor, actor_callback_type cb
, QObject *parent)
{
Expand All @@ -163,4 +180,61 @@ ActorHandle ActorImpl::createSync(qobj_ctor_type ctor, QObject *parent)
return result;
}

class AppExitMonitor : public QObject
{
Q_OBJECT
public:
AppExitMonitor(QCoreApplication *);
void insert(ActorHandle);
private slots:
void beforeAppQuit();
void actorFinished(Actor*);
private:
std::map<intptr_t, std::weak_ptr<Actor> > actors_;
};

static AppExitMonitor *monitor_;
static std::once_flag monitor_once_;

void deleteOnApplicationExit(ActorHandle h)
{
auto app = QCoreApplication::instance();
std::call_once(monitor_once_, [app]() {
monitor_ = new AppExitMonitor(app);
});
monitor_->insert(h);
}

AppExitMonitor::AppExitMonitor(QCoreApplication *app)
: QObject(app)
{
Q_ASSERT(app);
connect(app, SIGNAL(aboutToQuit())
, this, SLOT(beforeAppQuit()));
}

void AppExitMonitor::insert(ActorHandle p)
{
auto id = reinterpret_cast<intptr_t>(p.get());
actors_.insert(std::make_pair(id, std::weak_ptr<Actor>(p)));
connect(p.get(), &Actor::finished, this, &AppExitMonitor::actorFinished);
}

void AppExitMonitor::actorFinished(Actor *p)
{
auto id = reinterpret_cast<intptr_t>(p);
actors_.erase(id);
}

void AppExitMonitor::beforeAppQuit()
{
for (auto &kv : actors_) {
auto actor = kv.second.lock();
if (actor)
actor->quitSync(10000); // random timeout
}
}

}}

#include "mt.moc"

0 comments on commit de79566

Please sign in to comment.