@@ -334,6 +334,14 @@ module Controller = struct
334
334
module Log = Async_OpenFlow_Log
335
335
let tags = [(" openflow" , " openflow0x01" )]
336
336
337
+ (* We can not call read() on the same pipe concurrently.
338
+ Somehow this is happening sometimes, so we need to
339
+ enforce this invariant locally with condition variables. *)
340
+
341
+ let read_outstanding = ref false
342
+
343
+ let read_finished = Condition. create ()
344
+
337
345
module Client_id = ControllerProcess. Client_id
338
346
type t = ([ `Barrier of SwitchMap .key
339
347
| `Individual_stats of
@@ -381,36 +389,47 @@ module Controller = struct
381
389
| `Send_pkt_out_resp of (unit , exn ) Result .t
382
390
| `Aggregate_stats_resp of (OpenFlow0x01_Stats .aggregateStats , exn ) Result .t
383
391
]) Channel .t
392
+ let rec clear_to_read () = if (! read_outstanding)
393
+ then Condition. wait read_finished >> = clear_to_read
394
+ else return (read_outstanding := true )
395
+
396
+ let signal_read () = read_outstanding := false ;
397
+ Condition. broadcast read_finished ()
384
398
385
399
let aggregate_stats ?(pattern =C. match_all) (t : t ) sw_id =
400
+ clear_to_read () >> = fun () ->
386
401
Log. debug ~tags " aggregate_stats (local)" ;
387
402
Channel. write t (`Aggregate_stats (pattern, sw_id));
388
403
Channel. read t >> | function
389
- | `Aggregate_stats_resp resp -> resp
404
+ | `Aggregate_stats_resp resp -> signal_read () ; resp
390
405
391
406
let send_pkt_out (t : t ) (sw_id :Client_id.t ) pkt_out =
407
+ clear_to_read () >> = fun () ->
392
408
Log. debug ~tags " send_pkt_out (local)" ;
393
409
Channel. write t (`Send_pkt_out (sw_id, pkt_out));
394
410
Channel. read t >> | function
395
- | `Send_pkt_out_resp resp -> resp
411
+ | `Send_pkt_out_resp resp -> signal_read () ; resp
396
412
397
413
let send_flow_mods ?(clear =true ) (t : t ) (sw_id :Client_id.t ) flow_mods =
414
+ clear_to_read () >> = fun () ->
398
415
Log. debug ~tags " send_flow_mods (local)" ;
399
416
Channel. write t (`Send_flow_mods (clear, sw_id, flow_mods));
400
417
Channel. read t >> | function
401
- | `Send_flow_mods_resp resp -> resp
418
+ | `Send_flow_mods_resp resp -> signal_read () ; resp
402
419
403
420
let clear_flows ?(pattern =C. match_all) (t : t ) (sw_id :Client_id.t ) =
421
+ clear_to_read () >> = fun () ->
404
422
Log. debug ~tags " clear_flows (local)" ;
405
423
Channel. write t (`Clear_flows (pattern, sw_id));
406
424
Channel. read t >> | function
407
- | `Clear_flows_resp resp -> resp
425
+ | `Clear_flows_resp resp -> signal_read () ; resp
408
426
409
427
let get_switches (t : t ) =
428
+ clear_to_read () >> = fun () ->
410
429
Log. debug ~tags " get_switches (local)" ;
411
430
Channel. write t `Get_switches ;
412
431
Channel. read t >> | function
413
- | `Get_switches_resp resp -> resp
432
+ | `Get_switches_resp resp -> signal_read () ; resp
414
433
415
434
let set_kill_wait t (s :Time.Span.t ) =
416
435
Log. debug ~tags " set_kill_wait (local)" ;
@@ -425,16 +444,18 @@ module Controller = struct
425
444
Channel. write t (`Set_idle_wait s)
426
445
427
446
let listening_port (t : t ) =
447
+ clear_to_read () >> = fun () ->
428
448
Log. debug ~tags " set_listening_port (local)" ;
429
449
Channel. write t `Listening_port ;
430
450
Channel. read t >> | function
431
- | `Listening_port_resp resp -> resp
451
+ | `Listening_port_resp resp -> signal_read () ; resp
432
452
433
453
let client_addr_port (t : t ) sw_id =
454
+ clear_to_read () >> = fun () ->
434
455
Log. debug ~tags " client_addr_port (local)" ;
435
456
Channel. write t (`Client_addr_port sw_id);
436
457
Channel. read t >> | function
437
- | `Client_addr_port_resp resp -> resp
458
+ | `Client_addr_port_resp resp -> signal_read () ; resp
438
459
439
460
let send_to_all (t : t ) msg =
440
461
Log. debug ~tags " send_to_all (local)" ;
@@ -445,10 +466,11 @@ module Controller = struct
445
466
Channel. write t (`Send_ignore_errors (sw_id, msg))
446
467
447
468
let has_client_id (t : t ) sw_id =
469
+ clear_to_read () >> = fun () ->
448
470
Log. debug ~tags " has_client_id (local)" ;
449
471
Channel. write t (`Has_client_id sw_id);
450
472
Channel. read t >> | function
451
- | `Has_client_id_resp resp -> resp
473
+ | `Has_client_id_resp resp -> signal_read () ; resp
452
474
453
475
let close (t : t ) sw_id =
454
476
Log. debug ~tags " close (local)" ;
@@ -477,10 +499,11 @@ module Controller = struct
477
499
c
478
500
479
501
let send (t : t ) sw_id msg =
502
+ clear_to_read () >> = fun () ->
480
503
Log. debug ~tags " send (local)" ;
481
504
Channel. write t (`Send (sw_id, msg));
482
505
Channel. read t >> | function
483
- | `Send_resp resp -> resp
506
+ | `Send_resp resp -> signal_read () ; resp
484
507
485
508
let channel_transfer chan writer =
486
509
Deferred. forever () (fun _ -> Channel. read chan >> =
@@ -490,22 +513,26 @@ module Controller = struct
490
513
Channel. write t `Listen ;
491
514
let reader,writer = Pipe. create () in
492
515
don't_wait_for (
516
+ clear_to_read () >> = fun () ->
493
517
Log. debug ~tags " About to listen for listen_resp" ;
494
518
Channel. read t >> | function
495
519
| `Listen_resp chan -> Log. debug ~tags " Listen channel returned (local)" ;
520
+ signal_read () ;
496
521
Channel. write chan `Ready ;
497
522
channel_transfer chan writer);
498
523
reader
499
524
500
525
let barrier (t : t ) sw_id =
526
+ clear_to_read () >> = fun () ->
501
527
Log. debug ~tags " barrier (local)" ;
502
528
Channel. write t (`Barrier sw_id);
503
529
Channel. read t >> | function
504
- | `Barrier_resp resp -> resp
530
+ | `Barrier_resp resp -> signal_read () ; resp
505
531
506
532
let individual_stats ?(pattern =C. match_all) (t : t ) sw_id =
533
+ clear_to_read () >> = fun () ->
507
534
Log. debug ~tags " individual_stats (local)" ;
508
535
Channel. write t (`Individual_stats (pattern, sw_id));
509
536
Channel. read t >> | function
510
- | `Individual_stats_resp resp -> resp
537
+ | `Individual_stats_resp resp -> signal_read () ; resp
511
538
end
0 commit comments