Your browser does not seem to support JavaScript. As a result, your viewing experience will be diminished, and you have been placed in read-only mode . Please download a browser that supports JavaScript, or enable it if it's disabled (i.e. NoScript).

I have a QTimer * I allocate in a function running in a thread.
In the same function, I connect its timeout signal to a slot, then I set it as a single shot timer and start it.
Next, I call another function and sleep for a while waiting for the timer to expire and call the slot. The timer expires but the slot never gets called, by the way if a I call QCoreApplication::processEvents(); after the sleep time the slot gets called.
I do not understand this behavior and I do not know how obviate to this problem without calling the processEvents

Thank you in advance

if (!GetGwMgr->executeFirmwareCommissioning(identifier, commissioning.path, end_points)) { _task_mutex.lock(); _task_condition.wait(&_task_mutex); return; bool GWMgr::executeFirmwareCommissioning(QString identifier, QString commissioningPath, QList<QString> endPoints) return mOTAUpdateMgr.executeFirmwareCommissioning(identifier, commissioningPath, endPoints); bool OTAUpdateMgr::executeFirmwareCommissioning(QString id, QString fwPath, QList<QString> MACs) _evaluate_fsm_state_actions(OTAUpdateFSMState::commissioning); return true; void OTAUpdateMgr::_evaluate_fsm_state_actions(const OTAUpdateFSMState state) switch (state) { case OTAUpdateFSMState::commissioning: _init_commissioning_phase(); _launch_commissioning_phase(); break; case OTAUpdateFSMState::confirmed: if (_init_confirmed_state()) { _launch_confirmed_actions(); } else { _evaluate_fsm_state_actions(OTAUpdateFSMState::error); break; bool OTAUpdateMgr::_init_commissioning_phase() return true; bool OTAUpdateMgr::_launch_commissioning_phase() if (_first_message_timer == nullptr) { _first_message_timer = new QTimer(); for(auto nodeData: m_FSM.nodes) { if (!_first_message_timer->isActive()) { connect(_first_message_timer, &QTimer::timeout, this, &OTAUpdateMgr::_on_first_message_espiration); _first_message_timer->setSingleShot(true); _first_message_timer->start(sleep_time); _evaluate_fsm_state_actions(OTAUpdateFSMState::confirmed); return true; void OTAUpdateMgr::_on_first_message_espiration()

Notice the runTask is the entry point of a thread where all starts

@ulix
Are you expecting the single shot timer to timeout while runTask() is waiting on _task_condition.wait(&_task_mutex); ? It won't.

Separately: since you go new QTimer() without passing this as parent does your destructor delete this->_first_message_timer ? Or it seems to me simpler to put the QTimer as a member variable without the pointer/ new so it does not need freeing.

@JonB
I removed the mutex and the wait condition by temporarily substituting with a while but the behavior is the same: the timer expires but the slot is never invoked.
I do not know what to do

@ulix
You have a QTimer in a thread which does not run the Qt event loop, does it? So no signals will be delivered. Hence your finding:

The timer expires but the slot never gets called, by the way if a I call QCoreApplication::processEvents(); after the sleep time the slot gets called.

That processEvents() is the first time the evet loop is invoked. Your thread needs to be running the event loop all the time if that's where the timer is ticking (unless you move the timer to the main UI thread). See QThread::run() & QThread::exec() .