@@ -39,9 +39,11 @@ int libusbHandleEvents();
39
39
import "C"
40
40
41
41
import (
42
+ "context"
42
43
"errors"
43
44
"fmt"
44
45
"os"
46
+ "time"
45
47
46
48
"github.com/arduino/go-properties-orderedmap"
47
49
discovery "github.com/arduino/pluggable-discovery-protocol-handler/v2"
@@ -96,27 +98,62 @@ func (d *DFUDiscovery) libusbSync(eventCB discovery.EventCallback, errorCB disco
96
98
return errors .New (C .GoString (err ))
97
99
}
98
100
99
- closeChan := make (chan struct {})
101
+ ctx , cancel := context .WithCancel (context .Background ())
102
+ eventChan := d .runUpdateSender (ctx , eventCB , errorCB )
103
+
100
104
go func () {
101
- d .sendUpdates (eventCB , errorCB )
102
105
for {
103
106
if C .libusbHandleEvents () != 0 {
104
- d .sendUpdates (eventCB , errorCB )
107
+ select {
108
+ case eventChan <- true :
109
+ default :
110
+ }
105
111
}
106
112
select {
107
- case <- closeChan :
113
+ case <- ctx . Done () :
108
114
C .libusbHotplugDeregisterCallback ()
109
115
return
110
116
default :
111
117
}
112
118
}
113
119
}()
114
- d .close = func () {
115
- close (closeChan )
116
- }
120
+ d .close = cancel
117
121
return nil
118
122
}
119
123
124
+ func (d * DFUDiscovery ) runUpdateSender (ctx context.Context , eventCB discovery.EventCallback , errorCB discovery.ErrorCallback ) chan <- bool {
125
+ deviceEventChan := make (chan bool )
126
+ go func () {
127
+ d .sendUpdates (eventCB , errorCB )
128
+
129
+ for {
130
+ select {
131
+ case <- ctx .Done ():
132
+ return
133
+ case <- deviceEventChan :
134
+ }
135
+
136
+ again:
137
+ d .sendUpdates (eventCB , errorCB )
138
+
139
+ // Trigger another update after 500ms because the PLUG-IN signal may come
140
+ // way earlier before the port becomes actually READY.
141
+ // We experienced problems like:
142
+ // - the port not yet visibile
143
+ // - the port not accessible (because permissions haven't been set yet)
144
+ select {
145
+ case <- ctx .Done ():
146
+ return
147
+ case <- deviceEventChan :
148
+ goto again
149
+ case <- time .After (time .Millisecond * 500 ):
150
+ }
151
+ d .sendUpdates (eventCB , errorCB )
152
+ }
153
+ }()
154
+ return deviceEventChan
155
+ }
156
+
120
157
func (d * DFUDiscovery ) sendUpdates (eventCB discovery.EventCallback , errorCB discovery.ErrorCallback ) {
121
158
C .dfuProbeDevices ()
122
159
0 commit comments