mirror of https://github.com/v2ray/v2ray-core
Darien Raymond
7 years ago
44 changed files with 380 additions and 271 deletions
@ -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