@@ -343,17 +343,36 @@ void on_signal_callback(uv_signal_t* handle, int signum)
343343 context->stats ->totalSigusr1 += 1 ;
344344}
345345
346+ // / Invoke the callbacks for the mPendingRegionInfos
347+ void handleRegionCallbacks (ServiceRegistry& registry, std::vector<FairMQRegionInfo>& infos)
348+ {
349+ if (infos.empty () == false ) {
350+ std::vector<FairMQRegionInfo> toBeNotified;
351+ toBeNotified.swap (infos); // avoid any MT issue.
352+ for (auto const & info : toBeNotified) {
353+ registry.get <CallbackService>()(CallbackService::Id::RegionInfoCallback, info);
354+ }
355+ }
356+ }
357+
346358void DataProcessingDevice::InitTask ()
347359{
348360 for (auto & channel : fChannels ) {
349- channel.second .at (0 ).Transport ()->SubscribeToRegionEvents ([&pendingRegionInfos = mPendingRegionInfos , ®ionInfoMutex = mRegionInfoMutex ](FairMQRegionInfo info) {
361+ channel.second .at (0 ).Transport ()->SubscribeToRegionEvents ([this ,
362+ ®istry = mServiceRegistry ,
363+ &pendingRegionInfos = mPendingRegionInfos ,
364+ ®ionInfoMutex = mRegionInfoMutex ](FairMQRegionInfo info) {
350365 std::lock_guard<std::mutex> lock (regionInfoMutex);
351366 LOG (debug) << " >>> Region info event" << info.event ;
352367 LOG (debug) << " id: " << info.id ;
353368 LOG (debug) << " ptr: " << info.ptr ;
354369 LOG (debug) << " size: " << info.size ;
355370 LOG (debug) << " flags: " << info.flags ;
356371 pendingRegionInfos.push_back (info);
372+ // When not running we can handle the callbacks synchronously.
373+ if (this ->GetCurrentState () != fair::mq::State::Running) {
374+ handleRegionCallbacks (registry, pendingRegionInfos);
375+ }
357376 });
358377 }
359378
@@ -498,6 +517,12 @@ void DataProcessingDevice::Reset() { mServiceRegistry.get<CallbackService>()(Cal
498517
499518bool DataProcessingDevice::ConditionalRun ()
500519{
520+ // Notify on the main thread the new region callbacks, making sure
521+ // no callback is issued if there is something still processing.
522+ {
523+ std::lock_guard<std::mutex> lock (mRegionInfoMutex );
524+ handleRegionCallbacks (mServiceRegistry , mPendingRegionInfos );
525+ }
501526 // This will block for the correct delay (or until we get data
502527 // on a socket). We also do not block on the first iteration
503528 // so that devices which do not have a timer can still start an
@@ -529,15 +554,13 @@ bool DataProcessingDevice::ConditionalRun()
529554
530555 // Notify on the main thread the new region callbacks, making sure
531556 // no callback is issued if there is something still processing.
557+ // Notice that we still need to perform callbacks also after
558+ // the socket epolled, because otherwise we would end up serving
559+ // the callback after the first data arrives is the system is too
560+ // fast to transition from Init to Run.
532561 {
533562 std::lock_guard<std::mutex> lock (mRegionInfoMutex );
534- if (mPendingRegionInfos .empty () == false ) {
535- std::vector<FairMQRegionInfo> toBeNotified;
536- toBeNotified.swap (mPendingRegionInfos ); // avoid any MT issue.
537- for (auto const & info : toBeNotified) {
538- mServiceRegistry .get <CallbackService>()(CallbackService::Id::RegionInfoCallback, info);
539- }
540- }
563+ handleRegionCallbacks (mServiceRegistry , mPendingRegionInfos );
541564 }
542565
543566 assert (mStreams .size () == mHandles .size ());
0 commit comments