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();
        }
Example #2
0
 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);
 }
Example #3
0
        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.");
     });
 }
Example #5
0
        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);
        }
Example #8
0
        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);
            }
        }
Example #11
0
        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;
        }
Example #12
0
 public void Create_ValidSignal_Success(PosixSignal signal)
 {
     PosixSignalRegistration.Create(signal, ctx => { }).Dispose();
 }
Example #13
0
 public void Create_UninstallableSignal_Throws(PosixSignal signal)
 {
     Assert.Throws <IOException>(() => PosixSignalRegistration.Create(signal, ctx => { }));
 }
Example #14
0
 public void Create_InvalidSignal_Throws(PosixSignal signal)
 {
     Assert.Throws <PlatformNotSupportedException>(() => PosixSignalRegistration.Create(signal, ctx => { }));
 }
Example #15
0
 public void Create_NullHandler_Throws()
 {
     AssertExtensions.Throws <ArgumentNullException>("handler", () => PosixSignalRegistration.Create(PosixSignal.SIGCONT, null));
 }