Mercurial > hg > qm-dsp
comparison thread/AsynchronousTask.h @ 69:6afa0e011f74
* Fix some locking problems
| author | cannam |
|---|---|
| date | Thu, 21 May 2009 16:39:35 +0000 |
| parents | 09aba2ccd94a |
| children | 701233f8ed41 |
comparison
equal
deleted
inserted
replaced
| 68:09aba2ccd94a | 69:6afa0e011f74 |
|---|---|
| 9 | 9 |
| 10 #ifndef _ASYNCHRONOUS_TASK_H_ | 10 #ifndef _ASYNCHRONOUS_TASK_H_ |
| 11 #define _ASYNCHRONOUS_TASK_H_ | 11 #define _ASYNCHRONOUS_TASK_H_ |
| 12 | 12 |
| 13 #include "Thread.h" | 13 #include "Thread.h" |
| 14 | |
| 15 #include <iostream> | |
| 14 | 16 |
| 15 /** | 17 /** |
| 16 * AsynchronousTask provides a thread pattern implementation for | 18 * AsynchronousTask provides a thread pattern implementation for |
| 17 * threads which are used to perform a series of similar operations in | 19 * threads which are used to perform a series of similar operations in |
| 18 * parallel with other threads of the same type. | 20 * parallel with other threads of the same type. |
| 44 { | 46 { |
| 45 start(); | 47 start(); |
| 46 } | 48 } |
| 47 virtual ~AsynchronousTask() | 49 virtual ~AsynchronousTask() |
| 48 { | 50 { |
| 51 m_todo.lock(); | |
| 49 m_finishing = true; | 52 m_finishing = true; |
| 50 m_todo.signal(); | 53 m_todo.signal(); |
| 54 m_todo.unlock(); | |
| 51 wait(); | 55 wait(); |
| 52 } | 56 } |
| 53 | 57 |
| 54 // Subclass must provide methods to request task and obtain | 58 // Subclass must provide methods to request task and obtain |
| 55 // results, which the caller calls. The method that requests a | 59 // results, which the caller calls. The method that requests a |
| 59 // obtains results should call awaitTask() and then return any | 63 // obtains results should call awaitTask() and then return any |
| 60 // results from internal state. | 64 // results from internal state. |
| 61 | 65 |
| 62 protected: | 66 protected: |
| 63 void startTask() { | 67 void startTask() { |
| 68 m_done.lock(); | |
| 64 m_todo.lock(); | 69 m_todo.lock(); |
| 65 m_inTask = true; | 70 m_inTask = true; |
| 66 m_todo.signal(); | 71 m_todo.signal(); |
| 67 m_done.lock(); | |
| 68 m_todo.unlock(); | 72 m_todo.unlock(); |
| 69 } | 73 } |
| 70 void awaitTask() { | 74 void awaitTask() { |
| 71 m_done.lock(); | 75 m_done.wait(); |
| 72 while (m_inTask) m_done.wait(); | |
| 73 m_done.unlock(); | 76 m_done.unlock(); |
| 74 } | 77 } |
| 75 | 78 |
| 76 virtual void performTask() = 0; | 79 virtual void performTask() = 0; |
| 77 | 80 |
| 78 private: | 81 private: |
| 79 virtual void run() { | 82 virtual void run() { |
| 80 m_todo.lock(); | 83 m_todo.lock(); |
| 81 while (!m_finishing) { | 84 while (1) { |
| 82 while (!m_inTask && !m_finishing) { | 85 while (!m_inTask && !m_finishing) { |
| 83 m_todo.wait(); | 86 m_todo.wait(); |
| 84 } | 87 } |
| 85 if (m_finishing) { | 88 if (m_finishing) { |
| 89 m_done.lock(); | |
| 86 m_inTask = false; | 90 m_inTask = false; |
| 87 m_done.signal(); | 91 m_done.signal(); |
| 92 m_done.unlock(); | |
| 88 break; | 93 break; |
| 89 } | 94 } |
| 90 if (m_inTask) { | 95 performTask(); |
| 91 performTask(); | 96 m_done.lock(); |
| 92 m_inTask = false; | 97 m_inTask = false; |
| 93 m_done.signal(); | 98 m_done.signal(); |
| 94 } | 99 m_done.unlock(); |
| 95 } | 100 } |
| 96 m_todo.unlock(); | 101 m_todo.unlock(); |
| 97 } | 102 } |
| 98 | 103 |
| 99 Condition m_todo; | 104 Condition m_todo; |
