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; |