Skip to content

Commit cd676d1

Browse files
committed
Do not fork
1 parent 56088c2 commit cd676d1

File tree

1 file changed

+43
-21
lines changed

1 file changed

+43
-21
lines changed

Framework/Core/src/runDataProcessing.cxx

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -683,20 +683,22 @@ void handle_crash(int sig)
683683
}
684684

685685
/// This will start a new device by forking and executing a
686-
/// new child
687-
void spawnDevice(uv_loop_t* loop,
688-
DeviceRef ref,
689-
std::vector<DeviceSpec> const& specs,
690-
DriverInfo& driverInfo,
691-
std::vector<DeviceControl>&,
692-
std::vector<DeviceExecution>& executions,
693-
std::vector<DeviceInfo>& deviceInfos,
694-
std::vector<DataProcessingStates>& allStates,
695-
ServiceRegistryRef serviceRegistry,
696-
boost::program_options::variables_map& varmap,
697-
std::vector<DeviceStdioContext>& childFds,
698-
unsigned parentCPU,
699-
unsigned parentNode)
686+
/// new child.
687+
/// @return the PID of the new process (or 0 if we are in the driver)
688+
std::string spawnDevice(uv_loop_t* loop,
689+
DeviceRef ref,
690+
std::vector<DeviceSpec> const& specs,
691+
DriverInfo& driverInfo,
692+
DriverControl& driverControl,
693+
std::vector<DeviceControl>&,
694+
std::vector<DeviceExecution>& executions,
695+
std::vector<DeviceInfo>& deviceInfos,
696+
std::vector<DataProcessingStates>& allStates,
697+
ServiceRegistryRef serviceRegistry,
698+
boost::program_options::variables_map& varmap,
699+
std::vector<DeviceStdioContext>& childFds,
700+
unsigned parentCPU,
701+
unsigned parentNode)
700702
{
701703
// FIXME: this might not work when more than one DPL driver on the same
702704
// machine. Hopefully we do not care.
@@ -761,6 +763,15 @@ void spawnDevice(uv_loop_t* loop,
761763
putenv(strdup(DeviceSpecHelpers::reworkTimeslicePlaceholder(env, spec).data()));
762764
}
763765
execvp(execution.args[0], execution.args.data());
766+
// In the general case we never end up here, because execvp is used.
767+
// Once we move to plugins however, the run the plugin without loading
768+
// a new environment so the new pid can be used to identify.
769+
//
770+
// Let's stop immediately so that we can attach debuggers from here.
771+
driverControl.forcedTransitions = {
772+
DriverState::DO_CHILD,
773+
DriverState::BIND_GUI_PORT};
774+
return spec.id;
764775
} else {
765776
O2_SIGNPOST_ID_GENERATE(sid, driver);
766777
O2_SIGNPOST_EVENT_EMIT(driver, sid, "spawnDevice", "New child at %{pid}d", id);
@@ -844,6 +855,7 @@ void spawnDevice(uv_loop_t* loop,
844855

845856
// Let's add also metrics information for the given device
846857
gDeviceMetricsInfos.emplace_back(DeviceMetricsInfo{});
858+
return "";
847859
}
848860

849861
void processChildrenOutput(uv_loop_t* loop,
@@ -2108,15 +2120,25 @@ int runStateMachine(DataProcessorSpecs const& workflow,
21082120
runningWorkflow.devices[di], controls[di], deviceExecutions[di], infos, allStates);
21092121
} else {
21102122
DeviceRef ref{di};
2111-
spawnDevice(loop,
2112-
ref,
2113-
runningWorkflow.devices, driverInfo,
2114-
controls, deviceExecutions, infos,
2115-
allStates,
2116-
serviceRegistry, varmap,
2117-
childFds, parentCPU, parentNode);
2123+
frameworkId = spawnDevice(loop,
2124+
ref,
2125+
runningWorkflow.devices,
2126+
driverInfo,
2127+
driverControl,
2128+
controls, deviceExecutions, infos,
2129+
allStates,
2130+
serviceRegistry, varmap,
2131+
childFds, parentCPU, parentNode);
2132+
// We are in the child in this case. Do not continue spawning.
2133+
if (!frameworkId.empty()) {
2134+
break;
2135+
}
21182136
}
21192137
}
2138+
// Do not bother about the rest of the scheduling if we are in the child.
2139+
if (!frameworkId.empty()) {
2140+
break;
2141+
}
21202142
handleSignals();
21212143
handleChildrenStdio(&serverContext, forwardedStdin.str(), childFds, pollHandles);
21222144
for (auto& callback : postScheduleCallbacks) {

0 commit comments

Comments
 (0)