workerthread.cpp
1 /********************************************************************************
2  * FARSA Experiments Library *
3  * Copyright (C) 2007-2012 *
4  * Gianluca Massera <emmegian@yahoo.it> *
5  * Stefano Nolfi <stefano.nolfi@istc.cnr.it> *
6  * Tomassino Ferrauto <tomassino.ferrauto@istc.cnr.it> *
7  * *
8  * This program is free software; you can redistribute it and/or modify *
9  * it under the terms of the GNU General Public License as published by *
10  * the Free Software Foundation; either version 2 of the License, or *
11  * (at your option) any later version. *
12  * *
13  * This program is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16  * GNU General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU General Public License *
19  * along with this program; if not, write to the Free Software *
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
21  ********************************************************************************/
22 
23 #include "workerthread.h"
24 
25 namespace farsa {
26 
27 WorkerThread::WorkerThread( QObject* parent ) :
28  QThread(parent),
29  operations(),
30  mutex(),
31  waitForOperationsToDo(),
32  operation(NULL),
33  quitRequested(false),
34  exceptions() {
35 }
36 
38  foreach (BaseException *e, exceptions) {
39  delete e;
40  }
41 }
42 
44  mutex.lock();
45  operations.enqueue( newOperation );
46  mutex.unlock();
47  if ( operations.size() == 1 ) {
48  // wake the run thread because now there is something to do
49  waitForOperationsToDo.wakeAll();
50  }
51 }
52 
54  mutex.lock();
55  if ( operation ) {
56  operation->stop();
57  }
58  mutex.unlock();
59 }
60 
62  forever {
63  mutex.lock();
64  // We have to check quitRequested here (not only after waitForOperationsToDo.wait()) because quit() can
65  // be called before run() starts. In that case quitRequested is already true, but we lost the "signal"
66  // that should wake us when on the wait condition and so we would sleep indefinitely
67  if ( quitRequested ) {
68  mutex.unlock();
69  return;
70  }
71  if ( operations.size() == 0 ) {
72  // wait the adding of an operation
73  waitForOperationsToDo.wait( &mutex );
74  }
75  if ( quitRequested ) {
76  mutex.unlock();
77  return;
78  }
79  operation = operations.dequeue();
80  mutex.unlock();
81  try {
82  operation->run();
83  } catch (BaseException& e) {
84  BaseException* cloned = e.clone();
85  exceptions.append(cloned);
86 
87  emit exceptionDuringOperation(cloned);
88  } catch (...) {
90  exceptions.append(e);
91 
93  }
94  mutex.lock();
95  delete operation;
96  operation = NULL;
97  mutex.unlock();
98  if ( quitRequested ) {
99  return;
100  }
101  }
102 }
103 
105  mutex.lock();
106  quitRequested = true;
107  mutex.unlock();
109  waitForOperationsToDo.wakeAll();
110  wait();
111 }
112 
113 } // end namespace farsa