Skip to content

Commit e2126a0

Browse files
Merge pull request #156 from funny-falcon/future_selectable_lazy_chan
future/selectable: lazy allocate wait chan
2 parents 9398e38 + 5b1a630 commit e2126a0

File tree

1 file changed

+10
-2
lines changed

1 file changed

+10
-2
lines changed

futures/selectable.go

+10-2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ var ErrFutureCanceled = errors.New("future canceled")
3030
// Many simultaneous listeners may wait for result either with `f.Value()`
3131
// or by selecting/fetching from `f.WaitChan()`, which is closed when future
3232
// fulfilled.
33+
// Selectable contains sync.Mutex, so it is not movable/copyable.
3334
type Selectable struct {
3435
m sync.Mutex
3536
val interface{}
@@ -39,12 +40,17 @@ type Selectable struct {
3940
}
4041

4142
// NewSelectable returns new selectable future.
43+
// Note: this method is for backward compatibility.
44+
// You may allocate it directly on stack or embedding into larger structure
4245
func NewSelectable() *Selectable {
43-
return &Selectable{wait: make(chan struct{})}
46+
return &Selectable{}
4447
}
4548

4649
func (f *Selectable) wchan() <-chan struct{} {
4750
f.m.Lock()
51+
if f.wait == nil {
52+
f.wait = make(chan struct{})
53+
}
4854
ch := f.wait
4955
f.m.Unlock()
5056
return ch
@@ -77,7 +83,9 @@ func (f *Selectable) Fill(v interface{}, e error) error {
7783
atomic.StoreUint32(&f.filled, 1)
7884
w := f.wait
7985
f.wait = closed
80-
close(w)
86+
if w != nil {
87+
close(w)
88+
}
8189
}
8290
f.m.Unlock()
8391
return f.err

0 commit comments

Comments
 (0)