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/08/24 01:15:26 UTC

[mynewt-newtmgr] branch master updated (0d87660 -> 86e0ff2)

This is an automated email from the ASF dual-hosted git repository.

ccollins pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-newtmgr.git.


    from 0d87660  newtmgr - revendor
     new e2957b3  nmxact - Fix deadlock on fail-before-sync.
     new 3f8b260  nmxact - Minor comment changes.
     new 86e0ff2  newtmgr - revendor

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 newtmgr/Godeps/Godeps.json                         | 56 +++++++++++-----------
 .../newtmgr/nmxact/nmble/ble_util.go               |  6 ---
 .../newtmgr/nmxact/nmble/ble_xport.go              | 49 +++++++++----------
 .../mynewt.apache.org/newtmgr/nmxact/nmble/sync.go | 36 +++++++++-----
 .../newtmgr/nmxact/nmxutil/bcast.go                | 23 +++++++--
 nmxact/example/ble_scan/ble_scan.go                | 10 ++--
 nmxact/nmble/ble_util.go                           |  6 ---
 nmxact/nmble/ble_xport.go                          | 49 +++++++++----------
 nmxact/nmble/conn.go                               | 11 +++--
 nmxact/nmble/listen.go                             |  4 +-
 nmxact/nmble/sync.go                               | 36 +++++++++-----
 nmxact/nmxutil/bcast.go                            | 23 +++++++--
 12 files changed, 179 insertions(+), 130 deletions(-)

-- 
To stop receiving notification emails like this one, please contact
['"commits@mynewt.apache.org" <co...@mynewt.apache.org>'].

[mynewt-newtmgr] 02/03: nmxact - Minor comment changes.

Posted by cc...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ccollins pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-newtmgr.git

commit 3f8b260bcfe8490897a44137d151ad0100425e9b
Author: Christopher Collins <cc...@apache.org>
AuthorDate: Wed Aug 23 18:13:06 2017 -0700

    nmxact - Minor comment changes.
---
 nmxact/nmble/conn.go   | 11 +++++++----
 nmxact/nmble/listen.go |  4 ++--
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/nmxact/nmble/conn.go b/nmxact/nmble/conn.go
index e82b35e..f76907a 100644
--- a/nmxact/nmble/conn.go
+++ b/nmxact/nmble/conn.go
@@ -75,8 +75,9 @@ func (c *Conn) DisconnectChan() <-chan error {
 }
 
 func (c *Conn) abortNotifyListeners(err error) {
-	// No need to lock mutex; this should only be called after all go routines
-	// have terminated.
+	c.mtx.Lock()
+	defer c.mtx.Unlock()
+
 	for _, nl := range c.notifyMap {
 		nl.ErrChan <- err
 		close(nl.NotifyChan)
@@ -378,6 +379,7 @@ func (c *Conn) Connect(bx *BleXport, ownAddrType BleAddrType, peer BleDev,
 	return nil
 }
 
+// Opens the session for an already-established BLE connection.
 func (c *Conn) Inherit(connHandle uint16, bl *Listener) error {
 	if err := c.startConnecting(); err != nil {
 		return err
@@ -546,13 +548,14 @@ func (c *Conn) Profile() *Profile {
 	return &c.profile
 }
 
+// Indicates whether an error reported during MTU exchange is a "real" error or
+// not.  If the error was reported because MTU exchange already took place,
+// that isn't considered a real error.
 func isExchangeMtuError(err error) bool {
 	if err == nil {
 		return false
 	}
 
-	// If the operation failed because the peer already initiated the
-	// exchange, just pretend it was successful.
 	bhe := nmxutil.ToBleHost(err)
 	if bhe == nil {
 		return true
diff --git a/nmxact/nmble/listen.go b/nmxact/nmble/listen.go
index 19a1f2a..fe8ee61 100644
--- a/nmxact/nmble/listen.go
+++ b/nmxact/nmble/listen.go
@@ -81,8 +81,8 @@ func (bl *Listener) AfterTimeout(tmo time.Duration) <-chan time.Time {
 func (bl *Listener) Close() {
 	// This provokes a race condition.  The timer may get initialized at any
 	// time.
-	if bl.timer != nil {
-		bl.timer.Stop()
+	if t := bl.timer; t != nil {
+		nmxutil.StopAndDrainTimer(t)
 	}
 
 	// Mark the command as acked in case the race condition mentioned above

-- 
To stop receiving notification emails like this one, please contact
"commits@mynewt.apache.org" <co...@mynewt.apache.org>.

[mynewt-newtmgr] 01/03: nmxact - Fix deadlock on fail-before-sync.

Posted by cc...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ccollins pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-newtmgr.git

commit e2957b3bdf3bf6a0144fafd063f02ef445097b88
Author: Christopher Collins <cc...@apache.org>
AuthorDate: Wed Aug 23 15:23:35 2017 -0700

    nmxact - Fix deadlock on fail-before-sync.
---
 nmxact/example/ble_scan/ble_scan.go | 10 +++++---
 nmxact/nmble/ble_util.go            |  6 -----
 nmxact/nmble/ble_xport.go           | 49 +++++++++++++++++++------------------
 nmxact/nmble/sync.go                | 36 ++++++++++++++++++---------
 nmxact/nmxutil/bcast.go             | 23 ++++++++++++++---
 5 files changed, 74 insertions(+), 50 deletions(-)

diff --git a/nmxact/example/ble_scan/ble_scan.go b/nmxact/example/ble_scan/ble_scan.go
index 1fc7a41..dccb435 100644
--- a/nmxact/example/ble_scan/ble_scan.go
+++ b/nmxact/example/ble_scan/ble_scan.go
@@ -54,8 +54,10 @@ func configExitHandler(x xport.Xport, s sesn.Sesn) {
 			s := <-sigChan
 			switch s {
 			case os.Interrupt, syscall.SIGTERM:
-				onExit()
-				os.Exit(0)
+				go func() {
+					onExit()
+					os.Exit(0)
+				}()
 
 			case syscall.SIGQUIT:
 				util.PrintStacks()
@@ -81,8 +83,8 @@ func sendEcho(s sesn.Sesn) {
 
 func main() {
 	nmxutil.Debug = true
-	//nmxutil.SetLogLevel(log.DebugLevel)
-	nmxutil.SetLogLevel(log.InfoLevel)
+	nmxutil.SetLogLevel(log.DebugLevel)
+	//nmxutil.SetLogLevel(log.InfoLevel)
 
 	// Initialize the BLE transport.
 	params := nmble.NewXportCfg()
diff --git a/nmxact/nmble/ble_util.go b/nmxact/nmble/ble_util.go
index d41f867..fa9d151 100644
--- a/nmxact/nmble/ble_util.go
+++ b/nmxact/nmble/ble_util.go
@@ -21,7 +21,6 @@ package nmble
 
 import (
 	"fmt"
-	"runtime"
 	"sync"
 	"time"
 
@@ -59,11 +58,6 @@ func BhdTimeoutError(rspType MsgType, seq BleSeq) error {
 
 	log.Debug(str)
 
-	// XXX: Print stack trace; temporary change to debug timeout.
-	buf := make([]byte, 1024*1024)
-	stacklen := runtime.Stack(buf, true)
-	log.Debug(buf[:stacklen])
-
 	return nmxutil.NewXportError(str)
 }
 
diff --git a/nmxact/nmble/ble_xport.go b/nmxact/nmble/ble_xport.go
index e6bd23a..82e0549 100644
--- a/nmxact/nmble/ble_xport.go
+++ b/nmxact/nmble/ble_xport.go
@@ -229,9 +229,8 @@ func (bx *BleXport) shutdown(restart bool, err error) {
 		log.Debugf("Stopping BLE dispatcher")
 		bx.d.ErrorAll(err)
 
-		synced, err := bx.syncer.Refresh()
-		if err == nil && synced {
-			// Reset controller so that all outstanding connections terminate.
+		// Reset controller so that all outstanding connections terminate.
+		if bx.syncer.Synced() {
 			ResetXact(bx)
 		}
 
@@ -252,7 +251,7 @@ func (bx *BleXport) shutdown(restart bool, err error) {
 		// Indicate that the shutdown is complete.  If restarts are enabled on
 		// this transport, this signals that the transport should be started
 		// again.
-		bx.shutdownBlocker.UnblockAndRestart(restart)
+		bx.shutdownBlocker.Unblock(restart)
 	}()
 }
 
@@ -332,6 +331,7 @@ func (bx *BleXport) startOnce() error {
 		return nmxutil.NewXportError("BLE xport started twice")
 	}
 
+	bx.shutdownBlocker.Start()
 	bx.stopChan = make(chan struct{})
 
 	if err := bx.startUnixChild(); err != nil {
@@ -363,22 +363,7 @@ func (bx *BleXport) startOnce() error {
 		}
 	}()
 
-	if err := bx.syncer.Start(bx); err != nil {
-		bx.blockingShutdown(true, err)
-		return err
-	}
-
-	// Block until host and controller are synced.
-	if err := bx.syncer.BlockUntilSynced(
-		bx.cfg.SyncTimeout, bx.stopChan); err != nil {
-
-		err = nmxutil.NewXportError(
-			"Error waiting for host <-> controller sync: " + err.Error())
-		bx.blockingShutdown(true, err)
-		return err
-	}
-
-	// Host and controller are synced.  Listen for events in the background:
+	// Listen for events in the background:
 	//     * sync loss
 	//     * stack reset
 	//     * GATT access
@@ -393,9 +378,12 @@ func (bx *BleXport) startOnce() error {
 		}
 		defer bx.RemoveListener(accessl)
 
+		resetCh := bx.syncer.ListenReset()
+		syncCh := bx.syncer.ListenSync()
+
 		for {
 			select {
-			case reasonItf, ok := <-bx.syncer.ListenReset():
+			case reasonItf, ok := <-resetCh:
 				if ok {
 					// Only process the reset event if the transport is not
 					// already shutting down.  If in mid-shutdown, the reset
@@ -412,7 +400,7 @@ func (bx *BleXport) startOnce() error {
 					}
 				}
 
-			case syncedItf, ok := <-bx.syncer.ListenSync():
+			case syncedItf, ok := <-syncCh:
 				if ok {
 					synced := syncedItf.(bool)
 					if !synced {
@@ -443,6 +431,21 @@ func (bx *BleXport) startOnce() error {
 		}
 	}()
 
+	if err := bx.syncer.Start(bx); err != nil {
+		bx.blockingShutdown(true, err)
+		return err
+	}
+
+	// Block until host and controller are synced.
+	if err := bx.syncer.BlockUntilSynced(
+		bx.cfg.SyncTimeout, bx.stopChan); err != nil {
+
+		err = nmxutil.NewXportError(
+			"Error waiting for host <-> controller sync: " + err.Error())
+		bx.blockingShutdown(true, err)
+		return err
+	}
+
 	// Generate a new random address if none was specified.
 	var addr BleAddr
 	if bx.cfg.RandAddr != nil {
@@ -481,8 +484,6 @@ func (bx *BleXport) Start() error {
 		return nmxutil.NewXportError("BLE xport started twice")
 	}
 
-	bx.shutdownBlocker.Start()
-
 	// Try to start the transport.  If this first attempt fails, report the
 	// error and don't retry.
 	if err := bx.startOnce(); err != nil {
diff --git a/nmxact/nmble/sync.go b/nmxact/nmble/sync.go
index 95cae0f..a99e859 100644
--- a/nmxact/nmble/sync.go
+++ b/nmxact/nmble/sync.go
@@ -39,6 +39,10 @@ func (s *Syncer) Refresh() (bool, error) {
 	return synced, nil
 }
 
+func (s *Syncer) Synced() bool {
+	return s.synced
+}
+
 func (s *Syncer) checkSyncLoop() {
 	doneCh := make(chan struct{})
 
@@ -157,15 +161,10 @@ func (s *Syncer) listen() error {
 	return <-errChan
 }
 
-func (s *Syncer) shutdown() {
-	s.syncBcaster.Clear()
-	s.resetBcaster.Clear()
-	s.syncBlocker.Unblock(nil)
-
-	s.stopCh = nil
-}
-
 func (s *Syncer) Start(x *BleXport) error {
+	s.mtx.Lock()
+	defer s.mtx.Unlock()
+
 	s.x = x
 	s.stopCh = make(chan struct{})
 	s.syncBlocker.Start()
@@ -174,14 +173,27 @@ func (s *Syncer) Start(x *BleXport) error {
 }
 
 func (s *Syncer) Stop() error {
-	if s.stopCh == nil {
-		return fmt.Errorf("Syncer already stopped")
+	initiate := func() error {
+		s.mtx.Lock()
+		defer s.mtx.Unlock()
+
+		if s.stopCh == nil {
+			return fmt.Errorf("Syncer already stopped")
+		}
+		close(s.stopCh)
+		return nil
 	}
 
-	close(s.stopCh)
+	if err := initiate(); err != nil {
+		return err
+	}
 	s.wg.Wait()
 
-	s.shutdown()
+	s.syncBcaster.Clear()
+	s.resetBcaster.Clear()
+	s.syncBlocker.Unblock(nil)
+
+	s.stopCh = nil
 
 	return nil
 }
diff --git a/nmxact/nmxutil/bcast.go b/nmxact/nmxutil/bcast.go
index 27a2d61..2feba52 100644
--- a/nmxact/nmxutil/bcast.go
+++ b/nmxact/nmxutil/bcast.go
@@ -40,12 +40,23 @@ func (b *Bcaster) Listen() chan interface{} {
 
 func (b *Bcaster) Send(val interface{}) {
 	b.mtx.Lock()
-	chs := b.chs
-	b.mtx.Unlock()
+	defer b.mtx.Unlock()
 
-	for _, ch := range chs {
+	for _, ch := range b.chs {
 		ch <- val
-		close(ch)
+	}
+}
+
+func (b *Bcaster) StopListening(ch chan interface{}) {
+	b.mtx.Lock()
+	defer b.mtx.Unlock()
+
+	for i, c := range b.chs {
+		if c == ch {
+			b.chs[i] = b.chs[len(b.chs)-1]
+			b.chs = b.chs[:len(b.chs)-1]
+			break
+		}
 	}
 }
 
@@ -53,6 +64,10 @@ func (b *Bcaster) Clear() {
 	b.mtx.Lock()
 	defer b.mtx.Unlock()
 
+	for _, ch := range b.chs {
+		close(ch)
+	}
+
 	b.chs = nil
 }
 

-- 
To stop receiving notification emails like this one, please contact
"commits@mynewt.apache.org" <co...@mynewt.apache.org>.

[mynewt-newtmgr] 03/03: newtmgr - revendor

Posted by cc...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ccollins pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-newtmgr.git

commit 86e0ff2e5c362d85838eb97c22e83d644b604123
Author: Christopher Collins <cc...@apache.org>
AuthorDate: Wed Aug 23 15:11:06 2017 -0700

    newtmgr - revendor
---
 newtmgr/Godeps/Godeps.json                         | 56 +++++++++++-----------
 .../newtmgr/nmxact/nmble/ble_util.go               |  6 ---
 .../newtmgr/nmxact/nmble/ble_xport.go              | 49 +++++++++----------
 .../mynewt.apache.org/newtmgr/nmxact/nmble/sync.go | 36 +++++++++-----
 .../newtmgr/nmxact/nmxutil/bcast.go                | 23 +++++++--
 5 files changed, 96 insertions(+), 74 deletions(-)

diff --git a/newtmgr/Godeps/Godeps.json b/newtmgr/Godeps/Godeps.json
index 09fb727..b94c1f2 100644
--- a/newtmgr/Godeps/Godeps.json
+++ b/newtmgr/Godeps/Godeps.json
@@ -127,73 +127,73 @@
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/adv",
-			"Comment": "mynewt_1_1_0_tag-70-g84fed9d",
-			"Rev": "84fed9dc5e9680dbcfa5a66b0c4d243807e6cd60"
+			"Comment": "mynewt_1_1_0_tag-72-g4bab771",
+			"Rev": "4bab771175fae622e2193415cb56fd4bf8008e0f"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/bledefs",
-			"Comment": "mynewt_1_1_0_tag-70-g84fed9d",
-			"Rev": "84fed9dc5e9680dbcfa5a66b0c4d243807e6cd60"
+			"Comment": "mynewt_1_1_0_tag-72-g4bab771",
+			"Rev": "4bab771175fae622e2193415cb56fd4bf8008e0f"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/mgmt",
-			"Comment": "mynewt_1_1_0_tag-70-g84fed9d",
-			"Rev": "84fed9dc5e9680dbcfa5a66b0c4d243807e6cd60"
+			"Comment": "mynewt_1_1_0_tag-72-g4bab771",
+			"Rev": "4bab771175fae622e2193415cb56fd4bf8008e0f"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/nmble",
-			"Comment": "mynewt_1_1_0_tag-70-g84fed9d",
-			"Rev": "84fed9dc5e9680dbcfa5a66b0c4d243807e6cd60"
+			"Comment": "mynewt_1_1_0_tag-72-g4bab771",
+			"Rev": "4bab771175fae622e2193415cb56fd4bf8008e0f"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/nmp",
-			"Comment": "mynewt_1_1_0_tag-70-g84fed9d",
-			"Rev": "84fed9dc5e9680dbcfa5a66b0c4d243807e6cd60"
+			"Comment": "mynewt_1_1_0_tag-72-g4bab771",
+			"Rev": "4bab771175fae622e2193415cb56fd4bf8008e0f"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/nmserial",
-			"Comment": "mynewt_1_1_0_tag-70-g84fed9d",
-			"Rev": "84fed9dc5e9680dbcfa5a66b0c4d243807e6cd60"
+			"Comment": "mynewt_1_1_0_tag-72-g4bab771",
+			"Rev": "4bab771175fae622e2193415cb56fd4bf8008e0f"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/nmxutil",
-			"Comment": "mynewt_1_1_0_tag-70-g84fed9d",
-			"Rev": "84fed9dc5e9680dbcfa5a66b0c4d243807e6cd60"
+			"Comment": "mynewt_1_1_0_tag-72-g4bab771",
+			"Rev": "4bab771175fae622e2193415cb56fd4bf8008e0f"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/oic",
-			"Comment": "mynewt_1_1_0_tag-70-g84fed9d",
-			"Rev": "84fed9dc5e9680dbcfa5a66b0c4d243807e6cd60"
+			"Comment": "mynewt_1_1_0_tag-72-g4bab771",
+			"Rev": "4bab771175fae622e2193415cb56fd4bf8008e0f"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/omp",
-			"Comment": "mynewt_1_1_0_tag-70-g84fed9d",
-			"Rev": "84fed9dc5e9680dbcfa5a66b0c4d243807e6cd60"
+			"Comment": "mynewt_1_1_0_tag-72-g4bab771",
+			"Rev": "4bab771175fae622e2193415cb56fd4bf8008e0f"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/scan",
-			"Comment": "mynewt_1_1_0_tag-70-g84fed9d",
-			"Rev": "84fed9dc5e9680dbcfa5a66b0c4d243807e6cd60"
+			"Comment": "mynewt_1_1_0_tag-72-g4bab771",
+			"Rev": "4bab771175fae622e2193415cb56fd4bf8008e0f"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/sesn",
-			"Comment": "mynewt_1_1_0_tag-70-g84fed9d",
-			"Rev": "84fed9dc5e9680dbcfa5a66b0c4d243807e6cd60"
+			"Comment": "mynewt_1_1_0_tag-72-g4bab771",
+			"Rev": "4bab771175fae622e2193415cb56fd4bf8008e0f"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/udp",
-			"Comment": "mynewt_1_1_0_tag-70-g84fed9d",
-			"Rev": "84fed9dc5e9680dbcfa5a66b0c4d243807e6cd60"
+			"Comment": "mynewt_1_1_0_tag-72-g4bab771",
+			"Rev": "4bab771175fae622e2193415cb56fd4bf8008e0f"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/xact",
-			"Comment": "mynewt_1_1_0_tag-70-g84fed9d",
-			"Rev": "84fed9dc5e9680dbcfa5a66b0c4d243807e6cd60"
+			"Comment": "mynewt_1_1_0_tag-72-g4bab771",
+			"Rev": "4bab771175fae622e2193415cb56fd4bf8008e0f"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/xport",
-			"Comment": "mynewt_1_1_0_tag-70-g84fed9d",
-			"Rev": "84fed9dc5e9680dbcfa5a66b0c4d243807e6cd60"
+			"Comment": "mynewt_1_1_0_tag-72-g4bab771",
+			"Rev": "4bab771175fae622e2193415cb56fd4bf8008e0f"
 		}
 	]
 }
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_util.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_util.go
index d41f867..fa9d151 100644
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_util.go
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_util.go
@@ -21,7 +21,6 @@ package nmble
 
 import (
 	"fmt"
-	"runtime"
 	"sync"
 	"time"
 
@@ -59,11 +58,6 @@ func BhdTimeoutError(rspType MsgType, seq BleSeq) error {
 
 	log.Debug(str)
 
-	// XXX: Print stack trace; temporary change to debug timeout.
-	buf := make([]byte, 1024*1024)
-	stacklen := runtime.Stack(buf, true)
-	log.Debug(buf[:stacklen])
-
 	return nmxutil.NewXportError(str)
 }
 
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_xport.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_xport.go
index e6bd23a..82e0549 100644
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_xport.go
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_xport.go
@@ -229,9 +229,8 @@ func (bx *BleXport) shutdown(restart bool, err error) {
 		log.Debugf("Stopping BLE dispatcher")
 		bx.d.ErrorAll(err)
 
-		synced, err := bx.syncer.Refresh()
-		if err == nil && synced {
-			// Reset controller so that all outstanding connections terminate.
+		// Reset controller so that all outstanding connections terminate.
+		if bx.syncer.Synced() {
 			ResetXact(bx)
 		}
 
@@ -252,7 +251,7 @@ func (bx *BleXport) shutdown(restart bool, err error) {
 		// Indicate that the shutdown is complete.  If restarts are enabled on
 		// this transport, this signals that the transport should be started
 		// again.
-		bx.shutdownBlocker.UnblockAndRestart(restart)
+		bx.shutdownBlocker.Unblock(restart)
 	}()
 }
 
@@ -332,6 +331,7 @@ func (bx *BleXport) startOnce() error {
 		return nmxutil.NewXportError("BLE xport started twice")
 	}
 
+	bx.shutdownBlocker.Start()
 	bx.stopChan = make(chan struct{})
 
 	if err := bx.startUnixChild(); err != nil {
@@ -363,22 +363,7 @@ func (bx *BleXport) startOnce() error {
 		}
 	}()
 
-	if err := bx.syncer.Start(bx); err != nil {
-		bx.blockingShutdown(true, err)
-		return err
-	}
-
-	// Block until host and controller are synced.
-	if err := bx.syncer.BlockUntilSynced(
-		bx.cfg.SyncTimeout, bx.stopChan); err != nil {
-
-		err = nmxutil.NewXportError(
-			"Error waiting for host <-> controller sync: " + err.Error())
-		bx.blockingShutdown(true, err)
-		return err
-	}
-
-	// Host and controller are synced.  Listen for events in the background:
+	// Listen for events in the background:
 	//     * sync loss
 	//     * stack reset
 	//     * GATT access
@@ -393,9 +378,12 @@ func (bx *BleXport) startOnce() error {
 		}
 		defer bx.RemoveListener(accessl)
 
+		resetCh := bx.syncer.ListenReset()
+		syncCh := bx.syncer.ListenSync()
+
 		for {
 			select {
-			case reasonItf, ok := <-bx.syncer.ListenReset():
+			case reasonItf, ok := <-resetCh:
 				if ok {
 					// Only process the reset event if the transport is not
 					// already shutting down.  If in mid-shutdown, the reset
@@ -412,7 +400,7 @@ func (bx *BleXport) startOnce() error {
 					}
 				}
 
-			case syncedItf, ok := <-bx.syncer.ListenSync():
+			case syncedItf, ok := <-syncCh:
 				if ok {
 					synced := syncedItf.(bool)
 					if !synced {
@@ -443,6 +431,21 @@ func (bx *BleXport) startOnce() error {
 		}
 	}()
 
+	if err := bx.syncer.Start(bx); err != nil {
+		bx.blockingShutdown(true, err)
+		return err
+	}
+
+	// Block until host and controller are synced.
+	if err := bx.syncer.BlockUntilSynced(
+		bx.cfg.SyncTimeout, bx.stopChan); err != nil {
+
+		err = nmxutil.NewXportError(
+			"Error waiting for host <-> controller sync: " + err.Error())
+		bx.blockingShutdown(true, err)
+		return err
+	}
+
 	// Generate a new random address if none was specified.
 	var addr BleAddr
 	if bx.cfg.RandAddr != nil {
@@ -481,8 +484,6 @@ func (bx *BleXport) Start() error {
 		return nmxutil.NewXportError("BLE xport started twice")
 	}
 
-	bx.shutdownBlocker.Start()
-
 	// Try to start the transport.  If this first attempt fails, report the
 	// error and don't retry.
 	if err := bx.startOnce(); err != nil {
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/sync.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/sync.go
index 95cae0f..a99e859 100644
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/sync.go
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/sync.go
@@ -39,6 +39,10 @@ func (s *Syncer) Refresh() (bool, error) {
 	return synced, nil
 }
 
+func (s *Syncer) Synced() bool {
+	return s.synced
+}
+
 func (s *Syncer) checkSyncLoop() {
 	doneCh := make(chan struct{})
 
@@ -157,15 +161,10 @@ func (s *Syncer) listen() error {
 	return <-errChan
 }
 
-func (s *Syncer) shutdown() {
-	s.syncBcaster.Clear()
-	s.resetBcaster.Clear()
-	s.syncBlocker.Unblock(nil)
-
-	s.stopCh = nil
-}
-
 func (s *Syncer) Start(x *BleXport) error {
+	s.mtx.Lock()
+	defer s.mtx.Unlock()
+
 	s.x = x
 	s.stopCh = make(chan struct{})
 	s.syncBlocker.Start()
@@ -174,14 +173,27 @@ func (s *Syncer) Start(x *BleXport) error {
 }
 
 func (s *Syncer) Stop() error {
-	if s.stopCh == nil {
-		return fmt.Errorf("Syncer already stopped")
+	initiate := func() error {
+		s.mtx.Lock()
+		defer s.mtx.Unlock()
+
+		if s.stopCh == nil {
+			return fmt.Errorf("Syncer already stopped")
+		}
+		close(s.stopCh)
+		return nil
 	}
 
-	close(s.stopCh)
+	if err := initiate(); err != nil {
+		return err
+	}
 	s.wg.Wait()
 
-	s.shutdown()
+	s.syncBcaster.Clear()
+	s.resetBcaster.Clear()
+	s.syncBlocker.Unblock(nil)
+
+	s.stopCh = nil
 
 	return nil
 }
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmxutil/bcast.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmxutil/bcast.go
index 27a2d61..2feba52 100644
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmxutil/bcast.go
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmxutil/bcast.go
@@ -40,12 +40,23 @@ func (b *Bcaster) Listen() chan interface{} {
 
 func (b *Bcaster) Send(val interface{}) {
 	b.mtx.Lock()
-	chs := b.chs
-	b.mtx.Unlock()
+	defer b.mtx.Unlock()
 
-	for _, ch := range chs {
+	for _, ch := range b.chs {
 		ch <- val
-		close(ch)
+	}
+}
+
+func (b *Bcaster) StopListening(ch chan interface{}) {
+	b.mtx.Lock()
+	defer b.mtx.Unlock()
+
+	for i, c := range b.chs {
+		if c == ch {
+			b.chs[i] = b.chs[len(b.chs)-1]
+			b.chs = b.chs[:len(b.chs)-1]
+			break
+		}
 	}
 }
 
@@ -53,6 +64,10 @@ func (b *Bcaster) Clear() {
 	b.mtx.Lock()
 	defer b.mtx.Unlock()
 
+	for _, ch := range b.chs {
+		close(ch)
+	}
+
 	b.chs = nil
 }
 

-- 
To stop receiving notification emails like this one, please contact
"commits@mynewt.apache.org" <co...@mynewt.apache.org>.