public void SignalHandlerCalledForKnownSignals(PosixSignal s) { RemoteExecutor.Invoke(signalStr => { PosixSignal signal = Enum.Parse <PosixSignal>(signalStr); using SemaphoreSlim semaphore = new(0); using var _ = PosixSignalRegistration.Create(signal, ctx => { Assert.Equal(signal, ctx.Signal); // Ensure signal doesn't cause the process to terminate. ctx.Cancel = true; semaphore.Release(); }); // Use 'kill' command with signal name to validate the signal pal mapping. string sigArg = signalStr.StartsWith("SIG") ? signalStr.Substring(3) : signalStr; using var process = Process.Start(new ProcessStartInfo { FileName = "/bin/sh", // Use a shell because not all platforms include a 'kill' executable. ArgumentList = { "-c", $"kill -s {sigArg} {Environment.ProcessId.ToString()}" } }); process.WaitForExit(); Assert.Equal(0, process.ExitCode); bool entered = semaphore.Wait(SuccessTimeout); Assert.True(entered); }, s.ToString()).Dispose(); }
private partial void RegisterShutdownHandlers() { // systemd only sends SIGTERM to the service process, so we only listen for that signal. // Other signals (ex. SIGINT/SIGQUIT) will be handled by the default .NET runtime signal handler // and won't cause a graceful shutdown of the systemd service. _sigTermRegistration = PosixSignalRegistration.Create(PosixSignal.SIGTERM, HandlePosixSignal); }
public void Dispose_Idempotent(PosixSignal signal) { PosixSignalRegistration registration = PosixSignalRegistration.Create(signal, ctx => { }); registration.Dispose(); registration.Dispose(); }
void CreateDanglingRegistration() { PosixSignalRegistration.Create(signal, ctx => { Assert.False(true, "Signal handler was called."); }); }
private partial void RegisterShutdownHandlers() { Action <PosixSignalContext> handler = HandlePosixSignal; _sigIntRegistration = PosixSignalRegistration.Create(PosixSignal.SIGINT, handler); _sigQuitRegistration = PosixSignalRegistration.Create(PosixSignal.SIGQUIT, handler); _sigTermRegistration = PosixSignalRegistration.Create(PosixSignal.SIGTERM, handler); }
public void ExternalConsoleManipulation_RegistrationRemoved_UnregisterSucceeds() { RemoteExecutor.Invoke(() => { PosixSignalRegistration r = PosixSignalRegistration.Create(PosixSignal.SIGINT, _ => { }); FreeConsole(); AllocConsole(); r.Dispose(); // validate this doesn't throw even though the use of Free/AllocConsole likely removed our registration }).Dispose(); }
public void SignalHandlerNotCalledWhenDisposed() { PosixSignal signal = PosixSignal.SIGCONT; PosixSignalRegistration.Create(signal, ctx => { Assert.False(true, "Signal handler was called."); }).Dispose(); kill(signal); Thread.Sleep(100); }
public void Create_RegisterForMultipleSignalsMultipletimes_Success() { var registrations = new List <PosixSignalRegistration>(); for (int iter = 0; iter < 3; iter++) { for (int i = 0; i < 2; i++) { foreach (object[] signal in SupportedSignals()) { registrations.Add(PosixSignalRegistration.Create((PosixSignal)signal[0], _ => { })); } } registrations.ForEach(r => r.Dispose()); } }
public void SignalHandlerCalledForRawSignals(PosixSignal s) { RemoteExecutor.Invoke((signalStr) => { PosixSignal signal = Enum.Parse <PosixSignal>(signalStr); using SemaphoreSlim semaphore = new(0); using var _ = PosixSignalRegistration.Create(signal, ctx => { Assert.Equal(signal, ctx.Signal); // Ensure signal doesn't cause the process to terminate. ctx.Cancel = true; semaphore.Release(); }); kill(signal); bool entered = semaphore.Wait(SuccessTimeout); Assert.True(entered); }, s.ToString()).Dispose(); }
public void SignalHandlerWorksForSecondRegistration() { PosixSignal signal = PosixSignal.SIGCONT; for (int i = 0; i < 2; i++) { using SemaphoreSlim semaphore = new(0); using var _ = PosixSignalRegistration.Create(signal, ctx => { Assert.Equal(signal, ctx.Signal); // Ensure signal doesn't cause the process to terminate. ctx.Cancel = true; semaphore.Release(); }); kill(signal); bool entered = semaphore.Wait(SuccessTimeout); Assert.True(entered); } }
public Application( OptionsAtStartup optionsAtStartup, IOptionsMonitor <Options> optionsMonitor, IManagedState <State> state, ISoulseekClient soulseekClient, IConnectionWatchdog connectionWatchdog, ITransferService transferService, IBrowseTracker browseTracker, IConversationTracker conversationTracker, IRoomTracker roomTracker, IRoomService roomService, IUserService userService, IShareService shareService, IPushbulletService pushbulletService, IHubContext <ApplicationHub> applicationHub, IHubContext <LogsHub> logHub) { Console.CancelKeyPress += (_, args) => { ShuttingDown = true; Log.Warning("Received SIGINT"); }; foreach (var signal in new[] { PosixSignal.SIGINT, PosixSignal.SIGQUIT, PosixSignal.SIGTERM }) { PosixSignalRegistration.Create(signal, context => { ShuttingDown = true; Log.Fatal("Received {Signal}", signal); }); } OptionsAtStartup = optionsAtStartup; OptionsMonitor = optionsMonitor; OptionsMonitor.OnChange(async options => await OptionsMonitor_OnChange(options)); PreviousOptions = OptionsMonitor.CurrentValue; CompiledSearchResponseFilters = OptionsAtStartup.Filters.Search.Request.Select(f => new Regex(f, RegexOptions.Compiled)); State = state; State.OnChange(state => State_OnChange(state)); Shares = shareService; Shares.StateMonitor.OnChange(state => ShareState_OnChange(state)); Transfers = transferService; BrowseTracker = browseTracker; ConversationTracker = conversationTracker; Pushbullet = pushbulletService; RoomService = roomService; Users = userService; ApplicationHub = applicationHub; LogHub = logHub; Program.LogEmitted += (_, log) => LogHub.EmitLogAsync(log); Client = soulseekClient; Client.DiagnosticGenerated += Client_DiagnosticGenerated; Client.TransferStateChanged += Client_TransferStateChanged; Client.TransferProgressUpdated += Client_TransferProgressUpdated; Client.BrowseProgressUpdated += Client_BrowseProgressUpdated; Client.UserStatusChanged += Client_UserStatusChanged; Client.PrivateMessageReceived += Client_PrivateMessageRecieved; Client.PrivateRoomMembershipAdded += (e, room) => Log.Information("Added to private room {Room}", room); Client.PrivateRoomMembershipRemoved += (e, room) => Log.Information("Removed from private room {Room}", room); Client.PrivateRoomModerationAdded += (e, room) => Log.Information("Promoted to moderator in private room {Room}", room); Client.PrivateRoomModerationRemoved += (e, room) => Log.Information("Demoted from moderator in private room {Room}", room); Client.PublicChatMessageReceived += Client_PublicChatMessageReceived; Client.RoomMessageReceived += Client_RoomMessageReceived; Client.Disconnected += Client_Disconnected; Client.Connected += Client_Connected; Client.LoggedIn += Client_LoggedIn; Client.StateChanged += Client_StateChanged; Client.DistributedNetworkStateChanged += Client_DistributedNetworkStateChanged; Client.DownloadDenied += (e, args) => Log.Information("Download of {Filename} from {Username} was denied: {Message}", args.Filename, args.Username, args.Message); Client.DownloadFailed += (e, args) => Log.Information("Download of {Filename} from {Username} failed", args.Filename, args.Username); ConnectionWatchdog = connectionWatchdog; }
public void Create_ValidSignal_Success(PosixSignal signal) { PosixSignalRegistration.Create(signal, ctx => { }).Dispose(); }
public void Create_UninstallableSignal_Throws(PosixSignal signal) { Assert.Throws <IOException>(() => PosixSignalRegistration.Create(signal, ctx => { })); }
public void Create_InvalidSignal_Throws(PosixSignal signal) { Assert.Throws <PlatformNotSupportedException>(() => PosixSignalRegistration.Create(signal, ctx => { })); }
public void Create_NullHandler_Throws() { AssertExtensions.Throws <ArgumentNullException>("handler", () => PosixSignalRegistration.Create(PosixSignal.SIGCONT, null)); }