Skip to content

Commit 65beae0

Browse files
committed
Fixed race conditions bug in streamers
1 parent f8d872a commit 65beae0

18 files changed

+62
-47
lines changed

.github/workflows/CI-ubuntu.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ jobs:
263263
steps:
264264
- name: Install dependencies
265265
run: |
266-
sudo apt install libopenslide0 libpocl2t64 xvfb libgl1 libopengl0 libusb-1.0-0 libxcb-xinerama0
266+
sudo apt install libopenslide0 libpocl2t64 xvfb libgl1 libopengl0 libusb-1.0-0 libxcb-xinerama0 libxcb-icccm4
267267
- name: Download artifacts
268268
uses: actions/download-artifact@v4
269269
with:

source/FAST/Algorithms/ImagePatch/ImageToBatchGenerator.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ void ImageToBatchGenerator::generateStream() {
3232
bool firstTime = true;
3333
while(!lastFrame) {
3434
{
35-
std::unique_lock<std::mutex> lock(m_stopMutex);
3635
if(m_stop) {
3736
m_streamIsStarted = false;
3837
m_firstFrameIsInserted = false;

source/FAST/Algorithms/ImagePatch/PatchGenerator.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -202,16 +202,13 @@ void PatchGenerator::generateStream() {
202202
frameAdded();
203203
}
204204
} catch(ThreadStopped &e) {
205-
std::unique_lock<std::mutex> lock(m_stopMutex);
206205
m_stop = true;
207206
break;
208207
}
209208
previousPatch = patch;
210-
std::unique_lock<std::mutex> lock(m_stopMutex);
211209
if(m_stop)
212210
break;
213211
}
214-
std::unique_lock<std::mutex> lock(m_stopMutex);
215212
if(m_stop) {
216213
//m_streamIsStarted = false;
217214
m_firstFrameIsInserted = false;
@@ -293,13 +290,11 @@ void PatchGenerator::generateStream() {
293290
//std::this_thread::sleep_for(std::chrono::seconds(2));
294291
}
295292
} catch(ThreadStopped &e) {
296-
std::unique_lock<std::mutex> lock(m_stopMutex);
297293
m_stop = true;
298294
break;
299295
}
300296
mRuntimeManager->stopRegularTimer("create patch");
301297
previousPatch = patch;
302-
std::unique_lock<std::mutex> lock(m_stopMutex);
303298
if(m_stop)
304299
break;
305300
}}}

source/FAST/Algorithms/Interleave/Interleave.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ void Interleave::generateStream() {
3131
auto previousTime = std::chrono::high_resolution_clock::now();
3232
while(!lastFrame) {
3333
{
34-
std::unique_lock<std::mutex> lock(m_stopMutex);
3534
if(m_stop) {
3635
m_streamIsStarted = false;
3736
m_firstFrameIsInserted = false;
@@ -129,7 +128,6 @@ void InterleavePlayback::generateStream() {
129128
pause = getPause();
130129

131130
{
132-
std::unique_lock<std::mutex> lock(m_stopMutex);
133131
if(m_stop) {
134132
m_streamIsStarted = false;
135133
m_firstFrameIsInserted = false;

source/FAST/Algorithms/TissueMicroArrayExtractor/TissueMicroArrayExtractor.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,6 @@ void TissueMicroArrayExtractor::generateStream() {
113113
frameAdded();
114114
}
115115
} catch(ThreadStopped &e) {
116-
std::unique_lock<std::mutex> lock(m_stopMutex);
117116
m_stop = true;
118117
break;
119118
}

source/FAST/ProcessObject.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -195,11 +195,10 @@ void ProcessObject::addOutputData(uint portID, DataObject::pointer data, bool pr
195195

196196
// Add it to all output connections, if any connections exist
197197
if(mOutputConnections.count(portID) > 0) {
198-
for(auto output : mOutputConnections.at(portID)) {
199-
if(!output.expired()) {
200-
DataChannel::pointer port = output.lock();
198+
for(const auto& output : mOutputConnections.at(portID)) {
199+
auto port = output.lock();
200+
if(port)
201201
port->addFrame(data);
202-
}
203202
}
204203
}
205204
}

source/FAST/Python/Tests/test_data_stream_object.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,16 @@ def test_data_stream_empty_generator():
1616
assert counter == 0
1717

1818

19-
# def test_data_stream_empty_file_streamer():
20-
# streamer = fast.ImageFileStreamer \
21-
# .create(fast.Config.getTestDataPath() + "/US/Heart/ApicalFourChamber/US-2D_#.mhd",)
22-
# streamer.setStartNumber(200) # Incorrect start number, will result in no frames
23-
#
24-
# counter = 0
25-
# with pytest.raises(RuntimeError):
26-
# for image in fast.DataStream(streamer):
27-
# counter += 1
28-
# assert counter == 0
19+
def test_data_stream_empty_file_streamer():
20+
streamer = fast.ImageFileStreamer \
21+
.create(fast.Config.getTestDataPath() + "/US/Heart/ApicalFourChamber/US-2D_#.mhd",)
22+
streamer.setStartNumber(200) # Incorrect start number, will result in no frames
23+
24+
counter = 0
25+
with pytest.raises(RuntimeError):
26+
for image in fast.DataStream(streamer):
27+
counter += 1
28+
assert counter == 0
2929

3030

3131
def test_data_stream_single():

source/FAST/Streamers/DicomMultiFrameStreamer.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@ void DicomMultiFrameStreamer::generateStream() {
112112
pause = getPause();
113113

114114
{
115-
std::unique_lock<std::mutex> lock(m_stopMutex);
116115
if(m_stop) {
117116
m_streamIsStarted = false;
118117
m_firstFrameIsInserted = false;

source/FAST/Streamers/FileStreamer.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ void FileStreamer::setFilenameFormats(std::vector<std::string> strs) {
102102
void FileStreamer::generateStream() {
103103
if(getNrOfFrames() == 0) {
104104
stopWithError("No frames were created by the FileStreamer");
105+
return;
105106
}
106107

107108
// Read timestamp file if available
@@ -140,7 +141,6 @@ void FileStreamer::generateStream() {
140141
pause = getPause();
141142

142143
{
143-
std::unique_lock<std::mutex> lock(m_stopMutex);
144144
if(m_stop) {
145145
m_streamIsStarted = false;
146146
m_firstFrameIsInserted = false;
@@ -153,6 +153,7 @@ void FileStreamer::generateStream() {
153153
std::string filename = getFilename(i, currentSequence);
154154
try {
155155
reportInfo() << "Filestreamer reading " << filename << reportEnd();
156+
// If this causes pure virtual method called error, it means derived class forgot to call stop() in destructor
156157
DataObject::pointer dataFrame = getDataFrame(filename);
157158

158159
// Timing

source/FAST/Streamers/ImageFileStreamer.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ class FAST_EXPORT ImageFileStreamer : public FileStreamer {
6969
*/
7070
void setGrayscale(bool grayscale);
7171
void loadAttributes() override;
72+
~ImageFileStreamer() { stop(); }; // FileStreamer derived classes must call stop() in destructor or you will get a pure virtual method called error
7273
protected:
7374
DataObject::pointer getDataFrame(std::string filename) override;
7475

0 commit comments

Comments
 (0)