Skip to content

Commit af7fc65

Browse files
committed
bridge: fix shutdown of not running bridge
1 parent 6b5300f commit af7fc65

File tree

4 files changed

+29
-11
lines changed

4 files changed

+29
-11
lines changed

bridge/device/cloud/manager.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"fmt"
2626
"reflect"
2727
"sync"
28+
"sync/atomic"
2829
"time"
2930

3031
"github.com/google/uuid"
@@ -96,6 +97,7 @@ type Manager struct {
9697
signedIn bool
9798
resourcesPublished bool
9899
done chan struct{}
100+
stopped atomic.Bool
99101
trigger chan bool
100102
loop *eventloop.Loop
101103
}
@@ -529,7 +531,10 @@ func (c *Manager) connect(ctx context.Context) error {
529531
}
530532

531533
func (c *Manager) Close() {
532-
c.done <- struct{}{}
534+
if !c.stopped.CompareAndSwap(false, true) {
535+
return
536+
}
537+
close(c.done)
533538
}
534539

535540
func (c *Manager) Unregister() {

bridge/device/device.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"context"
2424
"fmt"
2525
"log"
26+
"sync/atomic"
2627

2728
"github.com/google/uuid"
2829
"github.com/plgd-dev/device/v2/bridge/device/cloud"
@@ -69,6 +70,7 @@ type Device struct {
6970
loop *eventloop.Loop
7071
runLoop bool
7172
done chan struct{}
73+
stopped atomic.Bool
7274
}
7375

7476
func NewLogger(id uuid.UUID, level pkgLog.Level) pkgLog.Logger {
@@ -296,6 +298,9 @@ func (d *Device) HandleRequest(req *net.Request) (*pool.Message, error) {
296298
}
297299

298300
func (d *Device) Close() {
301+
if !d.stopped.CompareAndSwap(false, true) {
302+
return
303+
}
299304
if d.cloudManager != nil {
300305
d.cloudManager.Close()
301306
}
@@ -306,9 +311,6 @@ func (d *Device) Close() {
306311
resource.Close()
307312
}
308313
if d.runLoop {
309-
select {
310-
case d.done <- struct{}{}:
311-
default:
312-
}
314+
close(d.done)
313315
}
314316
}

bridge/net/network.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ type Net struct {
5454

5555
servers coAPServers
5656
serving atomic.Bool
57+
stopped atomic.Bool
58+
wg sync.WaitGroup
5759
done chan struct{}
5860
cache *coapCache.Cache[int32, bool]
5961
}
@@ -357,7 +359,9 @@ func New(cfg Config, handler RequestHandler, logger log.Logger) (*Net, error) {
357359
cache: coapCache.NewCache[int32, bool](),
358360
}
359361
m.DefaultHandle(mux.HandlerFunc(n.ServeCOAP))
362+
n.wg.Add(1)
360363
go func() {
364+
defer n.wg.Done()
361365
for {
362366
select {
363367
case <-n.done:
@@ -417,10 +421,12 @@ func (n *Net) GetEndpoints(cm *net.ControlMessage, localAddr string) schema.Endp
417421
}
418422

419423
func (n *Net) Serve() error {
424+
if n.stopped.Load() {
425+
return fmt.Errorf("already stopped")
426+
}
420427
if !n.serving.CompareAndSwap(false, true) {
421428
return fmt.Errorf("already serving")
422429
}
423-
defer close(n.done)
424430
var wg sync.WaitGroup
425431
errCh := make(chan error, len(n.servers))
426432
wg.Add(len(n.servers))
@@ -446,10 +452,14 @@ func (n *Net) Serve() error {
446452
}
447453

448454
func (n *Net) Close() error {
455+
if !n.stopped.CompareAndSwap(false, true) {
456+
return nil
457+
}
458+
close(n.done)
459+
n.wg.Wait()
449460
if !n.serving.Load() {
450461
return n.servers.Close()
451462
}
452463
n.servers.Stop()
453-
<-n.done
454464
return nil
455465
}

bridge/service/service.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ package service
2020

2121
import (
2222
"fmt"
23+
"sync"
2324

2425
"github.com/google/uuid"
2526
"github.com/plgd-dev/device/v2/bridge/device"
@@ -66,7 +67,7 @@ type Service struct {
6667
cfg Config
6768
net *net.Net
6869
devices *coapSync.Map[uuid.UUID, Device]
69-
done chan struct{}
70+
wg sync.WaitGroup
7071
onDiscoveryDevices func(req *net.Request)
7172
}
7273

@@ -143,7 +144,6 @@ func New(cfg Config, opts ...Option) (*Service, error) {
143144
cfg: cfg,
144145
devices: coapSync.NewMap[uuid.UUID, Device](),
145146
onDiscoveryDevices: o.onDiscoveryDevices,
146-
done: make(chan struct{}),
147147
}
148148
n, err := net.New(cfg.API.CoAP.Config, c.DefaultRequestHandler, o.logger)
149149
if err != nil {
@@ -155,7 +155,8 @@ func New(cfg Config, opts ...Option) (*Service, error) {
155155
}
156156

157157
func (c *Service) Serve() error {
158-
defer close(c.done)
158+
c.wg.Add(1)
159+
defer c.wg.Done()
159160
return c.net.Serve()
160161
}
161162

@@ -164,7 +165,7 @@ func (c *Service) Shutdown() error {
164165
if err != nil {
165166
return err
166167
}
167-
<-c.done
168+
c.wg.Wait()
168169
devices := c.devices.LoadAndDeleteAll()
169170
for _, d := range devices {
170171
d.Close()

0 commit comments

Comments
 (0)