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