@@ -381,20 +381,18 @@ func runProgramAction(pme *packagemanager.Explorer,
381
381
uploadCtx , uploadCompleted := context .WithCancel (context .Background ())
382
382
defer uploadCompleted ()
383
383
384
- // By default do not return any new port but if there is an
385
- // expected port change then run the detector.
386
- updatedUploadPort := f .NewFuture [* discovery.Port ]()
387
- if uploadProperties .GetBoolean ("upload.wait_for_upload_port" ) {
388
- watcher , err := pme .DiscoveryManager ().Watch ()
389
- if err != nil {
390
- return nil , err
391
- }
392
- defer watcher .Close ()
393
-
394
- go detectUploadPort (uploadCtx , port , watcher .Feed (), updatedUploadPort )
395
- } else {
396
- updatedUploadPort .Send (nil )
384
+ // Start the upload port change detector.
385
+ watcher , err := pme .DiscoveryManager ().Watch ()
386
+ if err != nil {
387
+ return nil , err
397
388
}
389
+ defer watcher .Close ()
390
+ updatedUploadPort := f .NewFuture [* discovery.Port ]()
391
+ go detectUploadPort (
392
+ uploadCtx ,
393
+ port , watcher .Feed (),
394
+ uploadProperties .GetBoolean ("upload.wait_for_upload_port" ),
395
+ updatedUploadPort )
398
396
399
397
// Force port wait to make easier to unbrick boards like the Arduino Leonardo, or similar with native USB,
400
398
// when a sketch causes a crash and the native USB serial port is lost.
@@ -514,18 +512,19 @@ func runProgramAction(pme *packagemanager.Explorer,
514
512
uploadCompleted ()
515
513
logrus .Tracef ("Upload successful" )
516
514
517
- updatedPort := updatedUploadPort .Await ()
518
- if updatedPort == nil {
519
- return userPort , nil
520
- }
521
- return updatedPort .ToRPC (), nil
515
+ return updatedUploadPort .Await ().ToRPC (), nil
522
516
}
523
517
524
- func detectUploadPort (uploadCtx context.Context , uploadPort * discovery.Port , watch <- chan * discovery.Event , result f.Future [* discovery.Port ]) {
518
+ func detectUploadPort (
519
+ uploadCtx context.Context ,
520
+ uploadPort * discovery.Port , watch <- chan * discovery.Event ,
521
+ waitForUploadPort bool ,
522
+ result f.Future [* discovery.Port ],
523
+ ) {
525
524
log := logrus .WithField ("task" , "port_detection" )
526
525
log .Tracef ("Detecting new board port after upload" )
527
526
528
- var candidate * discovery. Port
527
+ candidate := uploadPort . Clone ()
529
528
defer func () {
530
529
result .Send (candidate )
531
530
}()
@@ -538,7 +537,13 @@ func detectUploadPort(uploadCtx context.Context, uploadPort *discovery.Port, wat
538
537
log .Error ("Upload port detection failed, watcher closed" )
539
538
return
540
539
}
541
- log .WithField ("event" , ev ).Trace ("Ignored watcher event before upload" )
540
+ if candidate != nil && ev .Type == "remove" && ev .Port .Equals (candidate ) {
541
+ log .WithField ("event" , ev ).Trace ("User-specified port has been disconnected, forcing waiting for upload port" )
542
+ waitForUploadPort = true
543
+ candidate = nil
544
+ } else {
545
+ log .WithField ("event" , ev ).Trace ("Ignored watcher event before upload" )
546
+ }
542
547
continue
543
548
case <- uploadCtx .Done ():
544
549
// Upload completed, move to the next phase
@@ -549,19 +554,25 @@ func detectUploadPort(uploadCtx context.Context, uploadPort *discovery.Port, wat
549
554
// Pick the first port that is detected after the upload
550
555
desiredHwID := uploadPort .HardwareID
551
556
timeout := time .After (5 * time .Second )
557
+ if ! waitForUploadPort {
558
+ timeout = time .After (time .Second )
559
+ }
552
560
for {
553
561
select {
554
562
case ev , ok := <- watch :
555
563
if ! ok {
556
564
log .Error ("Upload port detection failed, watcher closed" )
557
565
return
558
566
}
559
- if ev .Type == "remove" && candidate != nil {
560
- if candidate .Equals (ev .Port ) {
561
- log .WithField ("event" , ev ).Trace ("Candidate port is no more available" )
562
- candidate = nil
563
- continue
567
+ if candidate != nil && ev .Type == "remove" && candidate .Equals (ev .Port ) {
568
+ log .WithField ("event" , ev ).Trace ("Candidate port is no more available" )
569
+ candidate = nil
570
+ if ! waitForUploadPort {
571
+ waitForUploadPort = true
572
+ timeout = time .After (5 * time .Second )
573
+ log .Trace ("User-specified port has been disconnected, now waiting for upload port, timeout exteneded by 5 seconds" )
564
574
}
575
+ continue
565
576
}
566
577
if ev .Type != "add" {
567
578
log .WithField ("event" , ev ).Trace ("Ignored non-add event" )
0 commit comments