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