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 45b627eec53ead36b9f5ca7d020f582d7e949c8a
Author: Christopher Collins <ccoll...@apache.org>
AuthorDate: Fri Aug 25 17:22:24 2017 -0700

    nmxact - Fix BLE scanner deadlock.
---
 nmxact/nmble/ble_scanner.go | 39 +++++++++++++++++++++++++++------------
 1 file changed, 27 insertions(+), 12 deletions(-)

diff --git a/nmxact/nmble/ble_scanner.go b/nmxact/nmble/ble_scanner.go
index 3d2a05e..adb0a52 100644
--- a/nmxact/nmble/ble_scanner.go
+++ b/nmxact/nmble/ble_scanner.go
@@ -44,6 +44,7 @@ type BleScanner struct {
        reportedDevs   map[BleDev]string
        bos            *BleSesn
        enabled        bool
+       scanBlocker    nmxutil.Blocker
        suspendBlocker nmxutil.Blocker
 
        // Protects accesses to the reported devices map.
@@ -124,8 +125,8 @@ func (s *BleScanner) readHwId() (string, error) {
 
 func (s *BleScanner) scan() (*scan.ScanPeer, error) {
        // Ensure subsequent calls to suspend() block until scanning has 
stopped.
-       s.suspendBlocker.Start()
-       defer s.suspendBlocker.Unblock(nil)
+       s.scanBlocker.Start()
+       defer s.scanBlocker.Unblock(nil)
 
        // Discover the first device which matches the specified predicate.
        dev, err := s.discover()
@@ -191,7 +192,14 @@ func (s *BleScanner) Start(cfg scan.Cfg) error {
 
        // Start background scanning.
        go func() {
-               for s.enabled {
+               for {
+                       // Wait for suspend-in-progress to complete, if any.
+                       s.suspendBlocker.Wait(nmxutil.DURATION_FOREVER, nil)
+
+                       if !s.enabled {
+                               break
+                       }
+
                        p, err := s.scan()
                        if err != nil {
                                log.Debugf("Scan error: %s", err.Error())
@@ -210,6 +218,9 @@ func (s *BleScanner) Start(cfg scan.Cfg) error {
 }
 
 func (s *BleScanner) suspend() error {
+       s.suspendBlocker.Start()
+       defer s.suspendBlocker.Unblock(nil)
+
        discoverer := s.discoverer
        bos := s.bos
 
@@ -222,7 +233,7 @@ func (s *BleScanner) suspend() error {
        }
 
        // Block until scan is fully terminated.
-       s.suspendBlocker.Wait(nmxutil.DURATION_FOREVER, nil)
+       s.scanBlocker.Wait(nmxutil.DURATION_FOREVER, nil)
 
        s.discoverer = nil
        s.bos = nil
@@ -235,22 +246,26 @@ func (s *BleScanner) suspend() error {
 // master privileges.  When the high priority procedures are complete, scanning
 // will resume.
 func (s *BleScanner) Preempt() error {
-       s.mtx.Lock()
-       defer s.mtx.Unlock()
-
        return s.suspend()
 }
 
 // Stops the scanner.  Scanning won't resume unless Start() gets called.
 func (s *BleScanner) Stop() error {
-       s.mtx.Lock()
-       defer s.mtx.Unlock()
+       initiate := func() error {
+               s.mtx.Lock()
+               defer s.mtx.Unlock()
 
-       if !s.enabled {
-               return nmxutil.NewAlreadyError("Attempt to stop BLE scanner 
twice")
+               if !s.enabled {
+                       return nmxutil.NewAlreadyError("Attempt to stop BLE 
scanner twice")
+               }
+               s.enabled = false
+
+               return nil
        }
-       s.enabled = false
 
+       if err := initiate(); err != nil {
+               return err
+       }
        return s.suspend()
 }
 

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

Reply via email to