-
Notifications
You must be signed in to change notification settings - Fork 2
/
chans.go
56 lines (52 loc) · 881 Bytes
/
chans.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package genh
func SliceToChan[T any](s []T, cap int) <-chan T {
if cap == 0 {
cap = 1
}
ch := make(chan T, cap)
go func() {
for _, v := range s {
ch <- v
}
close(ch)
}()
return ch
}
func ChanToSlice[T any](s <-chan T, cap int) []T {
out := make([]T, cap)
for v := range s {
out = append(out, v)
}
return Clip(out)
}
func ClosedChan[T any]() chan T {
ch := make(chan T)
close(ch)
return ch
}
func SafeChan[T any](cap int) (ch <-chan T, pushFn func(T) bool, closeFn func()) {
var closed AtomicInt32
done := make(chan struct{})
rch := make(chan T, cap)
pushFn = func(v T) bool {
if closed.Load() > 0 {
return false
}
select {
case <-done:
if closed.CompareAndSwap(1, 2) {
close(rch)
}
return false
case rch <- v:
return true
}
}
closeFn = func() {
if closed.Swap(1) == 0 {
close(done)
}
}
ch = rch
return
}