PDA

View Full Version : Blocking a worker thread while waiting for user input



JayKemper
11th June 2015, 23:42
I have a worker object on a thread that is processing files. In some cases, the file needs user input to continue. So I need my worker to block until the user gives the input, and then it can continue.



class Worker : public QObject
{
Q_OBJECT(Worker)
public:
Worker();
~Worker();

protected slots:
void process()
{
...
if ( needInputFromUser )
emit signal_openDialog();

// Continue with processing

...
}

signals:
signal signal_openDialog();
}




class OnTheGUIThread : public QWindow
Q_OBJECT(OnTheGUIThread)
public:
OnTheGUIThread();
~OnTheGUIThread();

public:
void whereWorkerIsStarted()
{
...
QThread *thread = new QThread;
Worker *worker = new Worker;

connect(thread,SIGNAL(started()),worker,SLOT(proce ss()));
connect(worker,SIGNAL(signal_quit()),thread,SLOT(q uit()));

connect(worker,SIGNAL(signal_openDialog()),this,SL OT(slot_openDialog()),Qt::BlockingQueuedConnection );

thread->start();

...

}

protected slot:
void slot_openDialog()
{
dialog.exec(); // Blocks until window closed;
worker.setData(dialog.data());

return;
}


If I connect the openDialog signal/slots with a Qt::BlockingQueuedConnection, I get a deadlock. According to the documentation:

Same as QueuedConnection, except the current thread blocks until the slot returns. This connection type should only be used where the emitter and receiver are in different threads.

They are in different threads (or are they?), and I want the current thread to block until the slot returns. Am I just misunderstanding what it's used for?

Secondary question, what's the best way to pass data back to the processing thread?

jefftee
12th June 2015, 05:58
Hi, I don't see where you move the worker to the QThread you created. Did you just omit this from your post or have you not done that?

JayKemper
12th June 2015, 22:26
SOLVED!

I DIDN'T move the object to the thread. I was getting the desired effect (GUI updating while object ran in the background), but it wasn't until i tried this that it became a problem.

That's why I was so confused why the BlockingQueuedConnection wasn't working like I thought it should.

jefftee
12th June 2015, 23:53
Heh, glad I could help.

Regarding your other question about how to move data between threads, I've always used signal/slots since it simplifies passing data rather than having to lock a data structure with a mutex, etc. To each his own I guess, but using signals/slots hasn't presented any specific challenges and it just works.