Skip to content

Commit cc1a009

Browse files
ktfdavidrohr
authored andcommitted
DPL: fix race condition with the delivery of region events (#11961)
* DPL: fix race condition with the delivery of region events * Update Framework/Core/src/DataProcessingDevice.cxx
1 parent a60ac8f commit cc1a009

1 file changed

Lines changed: 12 additions & 3 deletions

File tree

Framework/Core/src/DataProcessingDevice.cxx

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -956,9 +956,12 @@ void DataProcessingDevice::InitTask()
956956
LOG(detail) << "ptr: " << info.ptr;
957957
LOG(detail) << "size: " << info.size;
958958
LOG(detail) << "flags: " << info.flags;
959-
context.expectedRegionCallbacks -= 1;
959+
// Now we check for pending events with the mutex,
960+
// so the lines below are atomic.
960961
pendingRegionInfos.push_back(info);
961-
// We always want to handle these on the main loop
962+
context.expectedRegionCallbacks -= 1;
963+
// We always want to handle these on the main loop,
964+
// so we awake it.
962965
ServiceRegistryRef ref{registry};
963966
uv_async_send(ref.get<DeviceState>().awakeMainThread);
964967
});
@@ -990,11 +993,17 @@ void DataProcessingDevice::InitTask()
990993
// We will get there.
991994
this->fillContext(mServiceRegistry.get<DataProcessorContext>(ServiceRegistry::globalDeviceSalt()), deviceContext);
992995

996+
auto hasPendingEvents = [&mutex = mRegionInfoMutex, &pendingRegionInfos = mPendingRegionInfos](DeviceContext& deviceContext) {
997+
std::lock_guard<std::mutex> lock(mutex);
998+
return (pendingRegionInfos.empty() == false) || deviceContext.expectedRegionCallbacks > 0;
999+
};
9931000
/// We now run an event loop also in InitTask. This is needed to:
9941001
/// * Make sure region registration callbacks are invoked
9951002
/// on the main thread.
9961003
/// * Wait for enough callbacks to be delivered before moving to START
997-
while (deviceContext.expectedRegionCallbacks > 0 && uv_run(state.loop, UV_RUN_ONCE)) {
1004+
while (hasPendingEvents(deviceContext)) {
1005+
// Wait for the callback to signal its done, so that we do not busy wait.
1006+
uv_run(state.loop, UV_RUN_ONCE);
9981007
// Handle callbacks if any
9991008
{
10001009
std::lock_guard<std::mutex> lock(mRegionInfoMutex);

0 commit comments

Comments
 (0)