blob: 36ef1aa86f632bc1b6cb42438e8f7be9f126f28d [file] [log] [blame]
Jungho Ahncd175b82015-03-27 14:29:40 -07001// Copyright 2015 The Vanadium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package vif
6
7import (
8 "fmt"
9 "reflect"
10 "time"
11)
12
13// WaitForNotifications waits till all notifications in 'wants' have been received,
14// or the timeout expires.
15func WaitForNotifications(notify <-chan interface{}, timeout time.Duration, wants ...interface{}) error {
16 timer := make(<-chan time.Time)
17 if timeout > 0 {
18 timer = time.After(timeout)
19 }
20
21 received := make(map[interface{}]struct{})
22 want := make(map[interface{}]struct{})
23 for _, w := range wants {
24 want[w] = struct{}{}
25 }
26 for {
27 select {
28 case n := <-notify:
29 received[n] = struct{}{}
30 if _, exists := want[n]; !exists {
31 return fmt.Errorf("unexpected notification %v", n)
32 }
33 if reflect.DeepEqual(received, want) {
34 return nil
35 }
36 case <-timer:
37 if len(wants) == 0 {
38 // No notification wanted.
39 return nil
40 }
41 return fmt.Errorf("timeout after receiving %v", reflect.ValueOf(received).MapKeys())
42 }
43 }
44}