Mercurial > hg > svcore
comparison data/fileio/FileReadThread.cpp @ 455:3e0f1f7bec85
* Fix a nasty and long-standing race condition in MatrixFile's use of
FileReadThread that was causing crashes sometimes
author | Chris Cannam |
---|---|
date | Thu, 09 Oct 2008 20:10:28 +0000 |
parents | 1f15beefcd76 |
children | 29efe322ab47 |
comparison
equal
deleted
inserted
replaced
454:ba7aaacb7211 | 455:3e0f1f7bec85 |
---|---|
19 #include "base/Thread.h" | 19 #include "base/Thread.h" |
20 | 20 |
21 #include <iostream> | 21 #include <iostream> |
22 #include <unistd.h> | 22 #include <unistd.h> |
23 | 23 |
24 #define DEBUG_FILE_READ_THREAD 1 | 24 //#define DEBUG_FILE_READ_THREAD 1 |
25 | 25 |
26 FileReadThread::FileReadThread() : | 26 FileReadThread::FileReadThread() : |
27 m_nextToken(0), | 27 m_nextToken(0), |
28 m_exiting(false) | 28 m_exiting(false) |
29 { | 29 { |
136 bool cancelled = | 136 bool cancelled = |
137 m_cancelledRequests.find(token) != m_cancelledRequests.end() && | 137 m_cancelledRequests.find(token) != m_cancelledRequests.end() && |
138 m_newlyCancelled.find(token) == m_newlyCancelled.end(); | 138 m_newlyCancelled.find(token) == m_newlyCancelled.end(); |
139 | 139 |
140 return cancelled; | 140 return cancelled; |
141 } | |
142 | |
143 bool | |
144 FileReadThread::haveRequest(int token) | |
145 { | |
146 MutexLocker locker(&m_mutex, "FileReadThread::haveRequest::m_mutex"); | |
147 | |
148 bool found = false; | |
149 | |
150 if (m_queue.find(token) != m_queue.end()) { | |
151 found = true; | |
152 } else if (m_cancelledRequests.find(token) != m_cancelledRequests.end()) { | |
153 found = true; | |
154 } else if (m_readyRequests.find(token) != m_readyRequests.end()) { | |
155 found = true; | |
156 } | |
157 | |
158 return found; | |
141 } | 159 } |
142 | 160 |
143 bool | 161 bool |
144 FileReadThread::getRequest(int token, Request &request) | 162 FileReadThread::getRequest(int token, Request &request) |
145 { | 163 { |
242 << request.start << " failed" << std::endl; | 260 << request.start << " failed" << std::endl; |
243 request.size = 0; | 261 request.size = 0; |
244 } else { | 262 } else { |
245 if (r < 0) { | 263 if (r < 0) { |
246 ::perror("ERROR: FileReadThread::process: Read failed"); | 264 ::perror("ERROR: FileReadThread::process: Read failed"); |
265 std::cerr << "ERROR: FileReadThread::process: read of " | |
266 << request.size << " at " | |
267 << request.start << " failed" << std::endl; | |
247 request.size = 0; | 268 request.size = 0; |
248 } else if (r < ssize_t(request.size)) { | 269 } else if (r < ssize_t(request.size)) { |
249 std::cerr << "WARNING: FileReadThread::process: read " | 270 std::cerr << "WARNING: FileReadThread::process: read " |
250 << request.size << " returned only " << r << " bytes" | 271 << request.size << " returned only " << r << " bytes" |
251 << std::endl; | 272 << std::endl; |
265 | 286 |
266 if (m_queue.find(token) != m_queue.end() && !m_exiting) { | 287 if (m_queue.find(token) != m_queue.end() && !m_exiting) { |
267 m_queue.erase(token); | 288 m_queue.erase(token); |
268 m_readyRequests[token] = request; | 289 m_readyRequests[token] = request; |
269 #ifdef DEBUG_FILE_READ_THREAD | 290 #ifdef DEBUG_FILE_READ_THREAD |
270 std::cerr << "FileReadThread::process: done, marking as ready" << std::endl; | 291 std::cerr << "FileReadThread::process: done, marking as ready (success = " << m_readyRequests[token].successful << ")" << std::endl; |
271 #endif | 292 #endif |
272 } else { | 293 } else { |
273 #ifdef DEBUG_FILE_READ_THREAD | 294 #ifdef DEBUG_FILE_READ_THREAD |
274 std::cerr << "FileReadThread::process: request disappeared or exiting" << std::endl; | 295 if (m_exiting) { |
296 std::cerr << "FileReadThread::process: exiting" << std::endl; | |
297 } else { | |
298 std::cerr << "FileReadThread::process: request disappeared" << std::endl; | |
299 } | |
275 #endif | 300 #endif |
276 } | 301 } |
277 } | 302 } |
278 | 303 |
279 void | 304 void |