Skip to content

Commit cc0b04f

Browse files
arthurkehrwaldfreezy
authored andcommitted
Reliably kill MPF on shutdown and before start
1 parent fadc54d commit cc0b04f

File tree

1 file changed

+79
-43
lines changed

1 file changed

+79
-43
lines changed

Runtime/MpfWrangler.cs

Lines changed: 79 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -211,20 +211,24 @@ public async Task StartMpf(MachineState initialState, CancellationToken ct)
211211
);
212212

213213
ct.ThrowIfCancellationRequested();
214-
MpfState = MpfState.Starting;
215-
216-
if (_executableSource != MpfExecutableSource.AssumeRunning)
217-
_mpfProcess = StartMpfProcess();
218214

219215
try
220216
{
217+
MpfState = MpfState.Starting;
218+
KillAllMpfProcesses();
219+
220+
if (_executableSource != MpfExecutableSource.AssumeRunning)
221+
_mpfProcess = StartMpfProcess();
222+
221223
await ConnectToMpf(initialState, ct);
222224
}
223225
catch (Exception ex)
224226
{
225227
if (_mpfProcess != null && !_mpfProcess.HasExited)
226228
_mpfProcess.Kill();
227229

230+
KillAllMpfProcesses();
231+
228232
_mpfProcess?.Dispose();
229233
_mpfProcess = null;
230234
MpfState = MpfState.NotConnected;
@@ -286,47 +290,61 @@ await client.QuitAsync(
286290
deadline: DateTime.UtcNow.AddSeconds(1)
287291
);
288292
}
289-
catch (RpcException ex)
293+
finally
290294
{
291-
Logger.Error($"Failed to send quit message to MPF: {ex}");
292-
}
293-
294-
_mpfCommunicationCts?.Cancel();
295-
if (_receiveMpfCommandsTask != null)
296-
await _receiveMpfCommandsTask;
297-
298-
if (_mpfProcess != null && !_mpfProcess.HasExited)
299-
{
300-
// MPF should shut down on its own after receiving the Quit message.
301-
// If it is still running after one second, just kill it.
302-
var processExited = new TaskCompletionSource<bool>();
303-
_mpfProcess.Exited += new EventHandler(
304-
(sender, args) => processExited.TrySetResult(true)
305-
);
306-
307-
if (
308-
await Task.WhenAny(
309-
processExited.Task,
310-
Task.Delay(TimeSpan.FromSeconds(1))
311-
) != processExited.Task
312-
&& !_mpfProcess.HasExited
313-
)
314-
_mpfProcess.Kill();
295+
try
296+
{
297+
_mpfCommunicationCts?.Cancel();
298+
if (_receiveMpfCommandsTask != null)
299+
await _receiveMpfCommandsTask;
300+
}
301+
finally
302+
{
303+
try
304+
{
305+
if (_mpfProcess != null && !_mpfProcess.HasExited)
306+
{
307+
// MPF should shut down on its own after receiving the Quit
308+
// message. If it is still running after one second, just kill
309+
// it.
310+
var processExited = new TaskCompletionSource<bool>();
311+
_mpfProcess.Exited += new EventHandler(
312+
(sender, args) => processExited.TrySetResult(true)
313+
);
314+
315+
if (
316+
await Task.WhenAny(
317+
processExited.Task,
318+
Task.Delay(TimeSpan.FromSeconds(1))
319+
) != processExited.Task
320+
&& !_mpfProcess.HasExited
321+
)
322+
_mpfProcess.Kill();
323+
}
324+
else
325+
{
326+
await Task.Delay(TimeSpan.FromSeconds(1));
327+
KillAllMpfProcesses();
328+
}
329+
}
330+
finally
331+
{
332+
_receiveMpfCommandsTask = null;
333+
_mpfCommunicationCts?.Dispose();
334+
_mpfCommunicationCts = null;
335+
_mpfCommandStreamCall?.Dispose();
336+
_mpfCommandStreamCall = null;
337+
_mpfSwitchStreamCall?.Dispose();
338+
_mpfSwitchStreamCall = null;
339+
_grpcChannel?.Dispose();
340+
_grpcChannel = null;
341+
_mpfProcess?.Dispose();
342+
_mpfProcess = null;
343+
344+
MpfState = MpfState.NotConnected;
345+
}
346+
}
315347
}
316-
317-
_receiveMpfCommandsTask = null;
318-
_mpfCommunicationCts?.Dispose();
319-
_mpfCommunicationCts = null;
320-
_mpfCommandStreamCall?.Dispose();
321-
_mpfCommandStreamCall = null;
322-
_mpfSwitchStreamCall?.Dispose();
323-
_mpfSwitchStreamCall = null;
324-
_grpcChannel?.Dispose();
325-
_grpcChannel = null;
326-
_mpfProcess?.Dispose();
327-
_mpfProcess = null;
328-
329-
MpfState = MpfState.NotConnected;
330348
return;
331349
}
332350
}
@@ -684,5 +702,23 @@ private void ExecuteMpfCommand(Commands command)
684702
break;
685703
}
686704
}
705+
706+
private void KillAllMpfProcesses()
707+
{
708+
var mpfProcesses = Process.GetProcessesByName("mpf");
709+
try
710+
{
711+
foreach (var process in mpfProcesses)
712+
{
713+
if (!process.HasExited)
714+
process.Kill();
715+
}
716+
}
717+
finally
718+
{
719+
foreach (var process in mpfProcesses)
720+
process.Dispose();
721+
}
722+
}
687723
}
688724
}

0 commit comments

Comments
 (0)