2018-05-03 15:04:00 +02:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0
|
|
|
|
*
|
|
|
|
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
|
|
|
|
*/
|
|
|
|
|
2017-11-30 23:22:40 +01:00
|
|
|
package main
|
|
|
|
|
|
|
|
type Signal struct {
|
|
|
|
enabled AtomicBool
|
|
|
|
C chan struct{}
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewSignal() (s Signal) {
|
|
|
|
s.C = make(chan struct{}, 1)
|
|
|
|
s.Enable()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-02-04 19:18:44 +01:00
|
|
|
func (s *Signal) Close() {
|
|
|
|
close(s.C)
|
|
|
|
}
|
|
|
|
|
2017-11-30 23:22:40 +01:00
|
|
|
func (s *Signal) Disable() {
|
|
|
|
s.enabled.Set(false)
|
|
|
|
s.Clear()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Signal) Enable() {
|
|
|
|
s.enabled.Set(true)
|
|
|
|
}
|
|
|
|
|
2017-12-01 23:37:26 +01:00
|
|
|
/* Unblock exactly one listener
|
|
|
|
*/
|
2017-11-30 23:22:40 +01:00
|
|
|
func (s *Signal) Send() {
|
|
|
|
if s.enabled.Get() {
|
|
|
|
select {
|
|
|
|
case s.C <- struct{}{}:
|
|
|
|
default:
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-01 23:37:26 +01:00
|
|
|
/* Clear the signal if already fired
|
|
|
|
*/
|
2017-11-30 23:22:40 +01:00
|
|
|
func (s Signal) Clear() {
|
|
|
|
select {
|
|
|
|
case <-s.C:
|
|
|
|
default:
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-01 23:37:26 +01:00
|
|
|
/* Unblocks all listeners (forever)
|
|
|
|
*/
|
2017-11-30 23:22:40 +01:00
|
|
|
func (s Signal) Broadcast() {
|
2018-02-04 19:18:44 +01:00
|
|
|
if s.enabled.Get() {
|
|
|
|
close(s.C)
|
|
|
|
}
|
2017-11-30 23:22:40 +01:00
|
|
|
}
|
|
|
|
|
2017-12-01 23:37:26 +01:00
|
|
|
/* Wait for the signal
|
|
|
|
*/
|
2017-11-30 23:22:40 +01:00
|
|
|
func (s Signal) Wait() chan struct{} {
|
|
|
|
return s.C
|
|
|
|
}
|