launchpad.net/~rogpeppe/juju-core/500-errgo-fix@v0.0.0-20140213181702-000000002356/worker/terminationworker/worker.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package terminationworker
     5  
     6  import (
     7  	"launchpad.net/tomb"
     8  	"os"
     9  	"os/signal"
    10  	"syscall"
    11  
    12  	"launchpad.net/juju-core/worker"
    13  )
    14  
    15  // TerminationSignal is the signal that
    16  // indicates the agent should terminate
    17  // and uninstall itself.
    18  //
    19  // We do not use SIGTERM as SIGTERM is the
    20  // default signal used to initiate a graceful
    21  // shutdown.
    22  const TerminationSignal = syscall.SIGABRT
    23  
    24  // NewWorker returns a worker that wais for a
    25  
    26  type terminationWorker struct {
    27  	tomb tomb.Tomb
    28  }
    29  
    30  // TerminationSignal signal and exits with
    31  // ErrTerminateAgent.
    32  func NewWorker() worker.Worker {
    33  	u := &terminationWorker{}
    34  	go func() {
    35  		defer u.tomb.Done()
    36  		u.tomb.Kill(u.loop())
    37  	}()
    38  	return u
    39  }
    40  
    41  func (u *terminationWorker) Kill() {
    42  	u.tomb.Kill(nil)
    43  }
    44  
    45  func (u *terminationWorker) Wait() error {
    46  	return u.tomb.Wait()
    47  }
    48  
    49  func (u *terminationWorker) loop() (err error) {
    50  	c := make(chan os.Signal, 1)
    51  	signal.Notify(c, TerminationSignal)
    52  	defer signal.Stop(c)
    53  	select {
    54  	case <-c:
    55  		return worker.ErrTerminateAgent
    56  	case <-u.tomb.Dying():
    57  		return nil
    58  	}
    59  }