mirror of https://github.com/v2ray/v2ray-core
parent
a1ae4aa515
commit
efcb567273
@ -1,10 +1,23 @@
|
||||
package common
|
||||
|
||||
// Closable is the interface for objects that can release its resources.
|
||||
type Closable interface {
|
||||
// Close release all resources used by this object, including goroutines.
|
||||
Close() error
|
||||
}
|
||||
|
||||
// Close closes the obj if it is a Closable.
|
||||
func Close(obj interface{}) error {
|
||||
if c, ok := obj.(Closable); ok {
|
||||
return c.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Runnable is the interface for objects that can start to work and stop on demand.
|
||||
type Runnable interface {
|
||||
// Start starts the runnable object. Upon the method returning nil, the object begins to function properly.
|
||||
Start() error
|
||||
|
||||
// Close stops the object being working.
|
||||
Close()
|
||||
Closable
|
||||
}
|
||||
|
@ -0,0 +1,48 @@
|
||||
package signal
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Done struct {
|
||||
access sync.Mutex
|
||||
c chan struct{}
|
||||
closed bool
|
||||
}
|
||||
|
||||
func NewDone() *Done {
|
||||
return &Done{
|
||||
c: make(chan struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Done) Done() bool {
|
||||
select {
|
||||
case <-d.c:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Done) C() chan struct{} {
|
||||
return d.c
|
||||
}
|
||||
|
||||
func (d *Done) Wait() {
|
||||
<-d.c
|
||||
}
|
||||
|
||||
func (d *Done) Close() error {
|
||||
d.access.Lock()
|
||||
defer d.access.Unlock()
|
||||
|
||||
if d.closed {
|
||||
return nil
|
||||
}
|
||||
|
||||
d.closed = true
|
||||
close(d.c)
|
||||
|
||||
return nil
|
||||
}
|
@ -1,22 +1,22 @@
|
||||
package signal
|
||||
|
||||
type Notifier struct {
|
||||
c chan bool
|
||||
c chan struct{}
|
||||
}
|
||||
|
||||
func NewNotifier() *Notifier {
|
||||
return &Notifier{
|
||||
c: make(chan bool, 1),
|
||||
c: make(chan struct{}, 1),
|
||||
}
|
||||
}
|
||||
|
||||
func (n *Notifier) Signal() {
|
||||
select {
|
||||
case n.c <- true:
|
||||
case n.c <- struct{}{}:
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
func (n *Notifier) Wait() <-chan bool {
|
||||
func (n *Notifier) Wait() <-chan struct{} {
|
||||
return n.c
|
||||
}
|
||||
|
@ -1,23 +1,23 @@
|
||||
package signal
|
||||
|
||||
type Semaphore struct {
|
||||
token chan bool
|
||||
token chan struct{}
|
||||
}
|
||||
|
||||
func NewSemaphore(n int) *Semaphore {
|
||||
s := &Semaphore{
|
||||
token: make(chan bool, n),
|
||||
token: make(chan struct{}, n),
|
||||
}
|
||||
for i := 0; i < n; i++ {
|
||||
s.token <- true
|
||||
s.token <- struct{}{}
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Semaphore) Wait() <-chan bool {
|
||||
func (s *Semaphore) Wait() <-chan struct{} {
|
||||
return s.token
|
||||
}
|
||||
|
||||
func (s *Semaphore) Signal() {
|
||||
s.token <- true
|
||||
s.token <- struct{}{}
|
||||
}
|
||||
|
@ -0,0 +1,60 @@
|
||||
package signal
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type PeriodicTask struct {
|
||||
Interval time.Duration
|
||||
Execute func() error
|
||||
|
||||
access sync.Mutex
|
||||
timer *time.Timer
|
||||
closed bool
|
||||
}
|
||||
|
||||
func (t *PeriodicTask) checkedExecute() error {
|
||||
t.access.Lock()
|
||||
defer t.access.Unlock()
|
||||
|
||||
if t.closed {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := t.Execute(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.timer = time.AfterFunc(t.Interval, func() {
|
||||
t.checkedExecute()
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *PeriodicTask) Start() error {
|
||||
t.access.Lock()
|
||||
t.closed = false
|
||||
t.access.Unlock()
|
||||
|
||||
if err := t.checkedExecute(); err != nil {
|
||||
t.closed = true
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *PeriodicTask) Close() error {
|
||||
t.access.Lock()
|
||||
defer t.access.Unlock()
|
||||
|
||||
t.closed = true
|
||||
if t.timer != nil {
|
||||
t.timer.Stop()
|
||||
t.timer = nil
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Loading…
Reference in new issue