Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 1 addition & 6 deletions tsc/cmd/tsc/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ import (
"flag"
"fmt"
"os"
"os/signal"
"strings"
"syscall"

"github.com/microsoft/TypeScript/tsc/internal/api"
"github.com/microsoft/TypeScript/tsc/internal/bundled"
Expand Down Expand Up @@ -42,7 +40,7 @@ func parseAPIFlags(args []string) (apiFlags, error) {
return result, nil
}

func runAPI(args []string) int {
func runAPI(ctx context.Context, args []string) int {
flags, err := parseAPIFlags(args)
if err != nil {
return 2
Expand Down Expand Up @@ -77,9 +75,6 @@ func runAPI(args []string) int {

s := api.NewStdioServer(options)

ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()

if err := s.Run(ctx); err != nil {
fmt.Fprintln(os.Stderr, err)
return 1
Expand Down
6 changes: 2 additions & 4 deletions tsc/cmd/tsc/lsp.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import (
"fmt"
"os"
"os/exec"
"os/signal"
"syscall"
"time"

"github.com/microsoft/TypeScript/tsc/internal/bundled"
Expand All @@ -18,7 +16,7 @@ import (
"github.com/microsoft/TypeScript/tsc/internal/vfs/osvfs"
)

func runLSP(args []string) int {
func runLSP(ctx context.Context, args []string) int {
flag := flag.NewFlagSet("lsp", flag.ContinueOnError)
stdio := flag.Bool("stdio", false, "use stdio for communication")
pprofDir := flag.String("pprofDir", "", "Generate pprof CPU/memory profiles to the given directory.")
Expand Down Expand Up @@ -47,7 +45,7 @@ func runLSP(args []string) int {
typingsLocation := osvfs.GetGlobalTypingsCacheLocation()
cwd := tspath.RootedDirectoryPathFromAbsolute(core.Must(os.Getwd()))

ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
ctx, stop := context.WithCancel(ctx)
defer stop()

s := lsp.NewServer(&lsp.ServerOptions{
Expand Down
51 changes: 47 additions & 4 deletions tsc/cmd/tsc/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,60 @@ func main() {

func runMain() int {
core.ApplyDebugStackLimit()
return runWithSignals(run)
}

// The first signal requests cancellation and waits for the command's cleanup,
// including profile flushing. A second signal terminates without waiting.
func runWithSignals(run func(context.Context) int) int {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
signals := make(chan os.Signal, 2)
signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM)
defer signal.Stop(signals)

done := make(chan int, 1)
go func() {
done <- run(ctx)
}()

var interrupted os.Signal
for {
select {
case sig := <-signals:
if interrupted != nil {
osutil.ExitWithSignal(sig)
}
interrupted = sig
cancel()
case status := <-done:
cancel()
signal.Stop(signals)
if interrupted == nil {
// Account for a signal queued as the command finished.
select {
case sig := <-signals:
interrupted = sig
default:
return status
}
}
osutil.ExitWithSignal(interrupted)
return status
}
}
}

func run(ctx context.Context) int {
args := osutil.Args()[1:]
if len(args) > 0 {
switch args[0] {
case "--lsp":
return runLSP(args[1:])
return runLSP(ctx, args[1:])
case "--api":
return runAPI(args[1:])
return runAPI(ctx, args[1:])
}
}
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
defer stop()
result := execute.CommandLine(ctx, newSystem(), args, nil)
return int(result.Status)
}
Loading
Loading