Skip to content

Commit

Permalink
ADD: osutil.WaitForStop()
Browse files Browse the repository at this point in the history
  • Loading branch information
whoisnian committed Dec 11, 2023
1 parent 959024b commit 066d8a2
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 8 deletions.
17 changes: 14 additions & 3 deletions util/osutil/osutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,24 @@ package osutil
import (
"os"
"os/signal"
"syscall"
)

// WaitForInterrupt blocks until current process receives SIGINT.
func WaitForInterrupt() {
// WaitFor blocks until current process receives any of signals.
func WaitFor(signals ...os.Signal) {
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
signal.Notify(c, signals...)
defer signal.Stop(c)

<-c
}

// WaitForInterrupt blocks until current process receives SIGINT.
func WaitForInterrupt() {
WaitFor(syscall.SIGINT)
}

// WaitForStop blocks until current process receives SIGINT or SIGTERM.
func WaitForStop() {
WaitFor(syscall.SIGINT, syscall.SIGTERM)
}
37 changes: 32 additions & 5 deletions util/osutil/osutil_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,24 @@ package osutil_test
import (
"os"
"runtime"
"syscall"
"testing"
"time"

"github.com/whoisnian/glb/util/osutil"
)

const (
waitingTime = 50 * time.Millisecond
timeoutTime = 60 * time.Millisecond
)

func TestWaitForInterrupt(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skipf("sending os.Interrupt is not implemented for windows")
t.Skipf("sending syscall.SIGINT is not implemented for windows")
}

done := make(chan struct{})
waitingTime := 50 * time.Millisecond
timeoutTime := 10*time.Millisecond + waitingTime

go func() {
osutil.WaitForInterrupt()
close(done)
Expand All @@ -27,11 +30,35 @@ func TestWaitForInterrupt(t *testing.T) {
if err != nil {
t.Fatalf("os.FindProcess() error: %v", err)
}
time.AfterFunc(waitingTime, func() { p.Signal(os.Interrupt) })

time.AfterFunc(waitingTime, func() { p.Signal(syscall.SIGINT) })
select {
case <-done:
case <-time.After(timeoutTime):
t.Fatal("WaitForInterrupt timeout")
}
}

func TestWaitForStop(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skipf("sending syscall.SIGTERM is not implemented for windows")
}

done := make(chan struct{})
go func() {
osutil.WaitForStop()
close(done)
}()

p, err := os.FindProcess(os.Getpid())
if err != nil {
t.Fatalf("os.FindProcess() error: %v", err)
}

time.AfterFunc(waitingTime, func() { p.Signal(syscall.SIGTERM) })
select {
case <-done:
case <-time.After(timeoutTime):
t.Fatal("WaitForStop timeout")
}
}

0 comments on commit 066d8a2

Please sign in to comment.