You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2017/04/03 23:53:38 UTC
[1/3] incubator-mynewt-newt git commit: unixchild - prevent
half-started state
Repository: incubator-mynewt-newt
Updated Branches:
refs/heads/develop df674371e -> 9de7460f1
unixchild - prevent half-started state
This fix consists of two parts:
1. Remove thread-safety where it is not necessary. There weren't any
bugs here, but it was complicating the code needlessly.
2. Don't automatically restart the child process when it terminates. It
is up to the client to do this.
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/commit/1a0a9ef7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/tree/1a0a9ef7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/diff/1a0a9ef7
Branch: refs/heads/develop
Commit: 1a0a9ef725ab6ce5ba41855f4b681deae61f952c
Parents: df67437
Author: Christopher Collins <cc...@apache.org>
Authored: Fri Mar 31 16:42:41 2017 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Fri Mar 31 16:42:41 2017 -0700
----------------------------------------------------------------------
util/unixchild/unixchild.go | 128 ++++++++++++---------------------------
1 file changed, 39 insertions(+), 89 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/1a0a9ef7/util/unixchild/unixchild.go
----------------------------------------------------------------------
diff --git a/util/unixchild/unixchild.go b/util/unixchild/unixchild.go
index b8be35d..b417187 100644
--- a/util/unixchild/unixchild.go
+++ b/util/unixchild/unixchild.go
@@ -60,14 +60,12 @@ type Config struct {
Depth int
MaxMsgSz int
AcceptTimeout time.Duration
- Restart bool
}
type clientState uint32
const (
CLIENT_STATE_STOPPED clientState = iota
- CLIENT_STATE_STARTING
CLIENT_STATE_STARTED
CLIENT_STATE_STOPPING
)
@@ -81,11 +79,9 @@ type Client struct {
childArgs []string
maxMsgSz int
acceptTimeout time.Duration
- restart bool
stop chan bool
stopped chan bool
state clientState
- stateMutex sync.Mutex
}
func New(conf Config) *Client {
@@ -98,7 +94,6 @@ func New(conf Config) *Client {
ToChild: make(chan []byte, conf.Depth),
ErrChild: make(chan error),
acceptTimeout: conf.AcceptTimeout,
- restart: conf.Restart,
stop: make(chan bool),
stopped: make(chan bool),
}
@@ -110,42 +105,6 @@ func New(conf Config) *Client {
return c
}
-func (c *Client) getState() clientState {
- c.stateMutex.Lock()
- defer c.stateMutex.Unlock()
-
- return c.state
-}
-
-func (c *Client) setState(toState clientState) {
- c.stateMutex.Lock()
- defer c.stateMutex.Unlock()
-
- c.state = toState
-}
-
-func (c *Client) setStateIf(toState clientState,
- pred func(st clientState) bool) (bool, clientState) {
-
- c.stateMutex.Lock()
- defer c.stateMutex.Unlock()
-
- if pred(c.state) {
- c.state = toState
- return true, toState
- }
-
- return false, c.state
-
-}
-
-func (c *Client) setStateFrom(fromState clientState,
- toState clientState) (bool, clientState) {
-
- return c.setStateIf(toState,
- func(st clientState) bool { return st == fromState })
-}
-
func (c *Client) startChild() (*exec.Cmd, error) {
subProcess := exec.Command(c.childPath, c.childArgs...)
@@ -249,20 +208,18 @@ func (c *Client) handleChild(con net.Conn) {
}
func (c *Client) Stop() {
- ok, _ := c.setStateIf(CLIENT_STATE_STOPPING,
- func(st clientState) bool {
- return st != CLIENT_STATE_STOPPING
- })
- if !ok {
+ if c.state != CLIENT_STATE_STARTED {
return
}
+ c.state = CLIENT_STATE_STOPPING
log.Debugf("Stopping client")
c.stop <- true
select {
case <-c.stopped:
+ c.state = CLIENT_STATE_STOPPED
log.Debugf("Stopped client")
return
}
@@ -277,63 +234,56 @@ func (c *Client) acceptDeadline() *time.Time {
return &t
}
+func (c *Client) deleteSocket() {
+ log.Debugf("deleting socket")
+ os.Remove(c.sockPath)
+}
+
func (c *Client) Start() error {
- ok, state := c.setStateFrom(CLIENT_STATE_STOPPED, CLIENT_STATE_STARTING)
- if !ok {
- return fmt.Errorf("client in invalid state for stating: %d", state)
+ if c.state != CLIENT_STATE_STOPPED {
+ return fmt.Errorf("Attempt to start unixchild twice")
}
l, err := net.Listen("unix", c.sockPath)
if err != nil {
- c.setState(CLIENT_STATE_STOPPED)
return err
}
- var cmd *exec.Cmd
+ cmd, err := c.startChild()
+ if err != nil {
+ err = fmt.Errorf("unixchild start error: %s", err.Error())
+ log.Debugf("%s", err.Error())
+ c.deleteSocket()
+ return err
+ }
+
+ if t := c.acceptDeadline(); t != nil {
+ l.(*net.UnixListener).SetDeadline(*t)
+ }
+ fd, err := l.Accept()
+ if err != nil {
+ err = NewUcAcceptError(fmt.Sprintf("unixchild accept error: %s",
+ err.Error()))
+ c.deleteSocket()
+ return err
+ }
+
+ c.state = CLIENT_STATE_STARTED
go func() {
- for {
- var err error
- cmd, err = c.startChild()
- if err != nil {
- log.Debugf("unixchild start error: %s", err.Error())
- c.ErrChild <- fmt.Errorf("Child start error: %s", err.Error())
- } else {
- if t := c.acceptDeadline(); t != nil {
- l.(*net.UnixListener).SetDeadline(*t)
- }
- fd, err := l.Accept()
- if err != nil {
- text := fmt.Sprintf("unixchild accept error: %s",
- err.Error())
- c.ErrChild <- NewUcAcceptError(text)
- } else {
- c.setState(CLIENT_STATE_STARTED)
- c.handleChild(fd)
- c.ErrChild <- fmt.Errorf("Child exited")
- }
- }
- if c.getState() == CLIENT_STATE_STOPPING {
- log.Debugf("unixchild exit loop")
- return
- }
- time.Sleep(time.Second)
- }
+ c.handleChild(fd)
+ c.Stop()
+ c.ErrChild <- fmt.Errorf("child process terminated")
}()
go func() {
- select {
- case <-c.stop:
- if c.getState() == CLIENT_STATE_STARTED {
- l.Close()
- }
- if cmd != nil {
- cmd.Process.Kill()
- }
- log.Debugf("deleting socket")
- os.Remove(c.sockPath)
- c.stopped <- true
+ <-c.stop
+ l.Close()
+ if cmd != nil {
+ cmd.Process.Kill()
}
+ c.deleteSocket()
+ c.stopped <- true
}()
return nil
[3/3] incubator-mynewt-newt git commit: unixchild - Ensure socket
gets deleted on stop.
Posted by cc...@apache.org.
unixchild - Ensure socket gets deleted on stop.
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/commit/9de7460f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/tree/9de7460f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/diff/9de7460f
Branch: refs/heads/develop
Commit: 9de7460f1fc510d724a507692abcd8e45f9e5f02
Parents: 74d8512
Author: Christopher Collins <cc...@apache.org>
Authored: Mon Apr 3 16:48:20 2017 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Mon Apr 3 16:53:26 2017 -0700
----------------------------------------------------------------------
util/unixchild/unixchild.go | 2 ++
1 file changed, 2 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/9de7460f/util/unixchild/unixchild.go
----------------------------------------------------------------------
diff --git a/util/unixchild/unixchild.go b/util/unixchild/unixchild.go
index b417187..91930c0 100644
--- a/util/unixchild/unixchild.go
+++ b/util/unixchild/unixchild.go
@@ -219,6 +219,7 @@ func (c *Client) Stop() {
select {
case <-c.stopped:
+ c.deleteSocket()
c.state = CLIENT_STATE_STOPPED
log.Debugf("Stopped client")
return
@@ -246,6 +247,7 @@ func (c *Client) Start() error {
l, err := net.Listen("unix", c.sockPath)
if err != nil {
+ c.deleteSocket()
return err
}
[2/3] incubator-mynewt-newt git commit: Add PrintStacks util function.
Posted by cc...@apache.org.
Add PrintStacks util function.
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/commit/74d85128
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/tree/74d85128
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/diff/74d85128
Branch: refs/heads/develop
Commit: 74d851283af3c31e79cd6f0432c0aa02d93c13f5
Parents: 1a0a9ef
Author: Christopher Collins <cc...@apache.org>
Authored: Fri Mar 31 17:07:54 2017 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Fri Mar 31 17:07:54 2017 -0700
----------------------------------------------------------------------
util/util.go | 6 ++++++
1 file changed, 6 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/74d85128/util/util.go
----------------------------------------------------------------------
diff --git a/util/util.go b/util/util.go
index fa3e60f..3e144e6 100644
--- a/util/util.go
+++ b/util/util.go
@@ -620,3 +620,9 @@ func IntMin(a, b int) int {
return b
}
}
+
+func PrintStacks() {
+ buf := make([]byte, 1024*1024)
+ stacklen := runtime.Stack(buf, true)
+ fmt.Printf("*** goroutine dump\n%s\n*** end\n", buf[:stacklen])
+}