How can i protect function that is running inside QThread , so it will invoked only after it finished its work ?
-
hello ,
im invoking QThread and inside its run methods i have timer that invoking function that preforme some heavy actions that takes time
usiily more then the interval that trigger the timer ( but not allways ) .
what i need is to protect this method so only it can be invoked only if it done its job :
here is the code :
@NotificationThread::NotificationThread(QObject *parent)
:QThread(parent),
bWorking(false),
m_timerInterval(0)
{}
NotificationThread::~NotificationThread()
{
;
}void NotificationThread::fire()
{if(!bWorking)
{
m_mutex.lock(); // <-- this is not protection the GetUpdateTime method from invoking over and overbWorking = true; int size = groupsMarkedForUpdate.size(); if(MyApp::getInstance()->GetUpdateTime(batchVectorResult)) { bWorking = false; emit UpdateNotifications(); }
m_mutex.unlock();
}}
void NotificationThread::run()
{m_NotificationTimer = new QTimer();
connect(m_NotificationTimer, SIGNAL(timeout()),
this,SLOT(fire(),Qt::DirectConnection));int interval = val.toInt();
m_NotificationTimer->setInterval(3000);
m_NotificationTimer->start();QThread::exec();
}
// this method invoked from the main class
void NotificationThread::Execute(const QStringList batchReqList)
{m_batchReqList = batchReqList;
start();
}@ -
The answer depends on whether you want the GetUpdateTime() calls to "queue up" if a previous call is still running or whether you just want to discard the call until the next interval fires.
For the former: Use an atomic integer to store how many calls are "queued up". If the count is 0 then the call is successful. If it's > 0 increment it by one. Wrap the function's code in "while(count > 0)" and decrement at then end. The problem is the test has to be "transactional" because this "bug" could occur: T1 - is count > 0? yes it is 1, T2 - finished call. decrement count. count = 0. exit while loop, T1 - increment count. Thread 2 can decrement between Thread 1's test and set causing the function to exit. So you will need an atomic test-then-increment which I don't think is available without using a lock. http://doc.qt.nokia.com/qq/qq14-threading.html#theatomicoperations
For the latter: You can either have an atomic boolean as a flag for whether the function is running or you can have a QMutex as a flag and use tryLock() to just ignore the call if the lock attempt fails.
-
What reactive wanted to say is:
You have to options, when the timer fires and your function is still busy:You remember that the timer has fired and try to call GetUpdateTime, once it's available again, or
You just discard it and wait for the timer to fire again
Depending on what you want, we can help you with the code for either of those options.