From afd497e194e8374b848a3ab2f91f8b820010035f Mon Sep 17 00:00:00 2001 From: Konstantin Koroviev <kkoroviev@gmail.com> Date: Mon, 9 Mar 2015 15:43:10 +0200 Subject: [PATCH] Dirty hack to fix race conditions in the daemon --- cmd/ipfs/daemon.go | 4 ++++ cmd/ipfs/main.go | 11 +++++++++++ commands/request.go | 7 ++++--- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index b1d9d696e..7ccaf8776 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -267,6 +267,10 @@ func daemonFunc(req cmds.Request, res cmds.Response) { gateway.ServeOption(), corehttp.VersionOption(), } + + // our global interrupt handler can now try to stop the daemon + close(req.Context().ContextIsReadyToBeClosed) + if rootRedirect != nil { opts = append(opts, rootRedirect) } diff --git a/cmd/ipfs/main.go b/cmd/ipfs/main.go index 8dc1f9d0b..69050804c 100644 --- a/cmd/ipfs/main.go +++ b/cmd/ipfs/main.go @@ -132,6 +132,14 @@ func main() { os.Exit(1) } + // our global interrupt handler may try to stop the daemon + // before the daemon is ready to be stopped; this dirty + // workaround is for the daemon only; other commands are always + // ready to be stopped + if invoc.cmd != daemonCmd { + close(invoc.req.Context().ContextIsReadyToBeClosed) + } + // ok, finally, run the command invocation. output, err := invoc.Run(ctx) if err != nil { @@ -473,6 +481,9 @@ func (i *cmdInvocation) setupInterruptHandler() { sig := allInterruptSignals() go func() { + // wait till the context is ready to be closed + <-ctx.ContextIsReadyToBeClosed + // first time, try to shut down. // loop because we may be diff --git a/commands/request.go b/commands/request.go index c9748198b..6a5e05775 100644 --- a/commands/request.go +++ b/commands/request.go @@ -28,8 +28,9 @@ type Context struct { config *config.Config LoadConfig func(path string) (*config.Config, error) - node *core.IpfsNode - ConstructNode func() (*core.IpfsNode, error) + node *core.IpfsNode + ConstructNode func() (*core.IpfsNode, error) + ContextIsReadyToBeClosed chan bool } // GetConfig returns the config of the current Command exection @@ -287,7 +288,7 @@ func NewRequest(path []string, opts OptMap, args []string, file files.File, cmd optDefs = make(map[string]Option) } - ctx := Context{Context: context.TODO()} + ctx := Context{Context: context.TODO(), ContextIsReadyToBeClosed: make(chan bool)} values := make(map[string]interface{}) req := &request{path, opts, args, file, cmd, ctx, optDefs, values, os.Stdin} err := req.ConvertOptions() -- GitLab