////////////////////////////////////////////////////////////////////// // // Given is a mock process which runs indefinitely and blocks the // program. Right now the only way to stop the program is to send a // SIGINT (Ctrl-C). Killing a process like that is not graceful, so we // want to try to gracefully stop the process first. // // Change the program to do the following: // 1. On SIGINT try to gracefully stop the process using // `proc.Stop()` // 2. If SIGINT is called again, just kill the program (last resort) // package main import ( "os" "os/signal" "syscall" ) func solution1() { // Create a process proc := MockProcess{} sig := make(chan os.Signal, 1) signal.Notify(sig, syscall.SIGINT) // Run the process (blocking) go proc.Run() <-sig done := make(chan bool, 1) go func() { proc.Stop() done <- true }() select { case <-done: return case <-sig: return } } func solution2() { // Create a process proc := MockProcess{} go func() { c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt) <-c signal.Reset() // reset interrupt handler and get back to standard behaviour : killing the process proc.Stop() }() // Run the process (blocking) proc.Run() } func main() { solution1() solution2() // must run after Solution1 because the 2nd SIGINT will be fatal }