Browse Source

增加部分实用函数

pull/47/head
Sydonian 1 year ago
parent
commit
922ffc8693
4 changed files with 129 additions and 0 deletions
  1. +2
    -0
      utils/sync2/counter_cond.go
  2. +74
    -0
      utils/sync2/unbound_channel.go
  3. +28
    -0
      utils/time2/duration.go
  4. +25
    -0
      utils/time2/time2_test.go

+ 2
- 0
utils/sync2/counter_cond.go View File

@@ -32,7 +32,9 @@ func (c *CounterCond) Wait() bool {
} }


func (c *CounterCond) Release() { func (c *CounterCond) Release() {
c.cond.L.Lock()
c.count++ c.count++
c.cond.L.Unlock()
c.cond.Signal() c.cond.Signal()
} }




+ 74
- 0
utils/sync2/unbound_channel.go View File

@@ -0,0 +1,74 @@
package sync2

import (
"container/list"
"sync"
)

type UnboundChannel[T any] struct {
values *list.List
cond *sync.Cond
err error
}

func NewUnboundChannel[T any]() *UnboundChannel[T] {
return &UnboundChannel[T]{
values: list.New(),
cond: sync.NewCond(&sync.Mutex{}),
}
}

func (c *UnboundChannel[T]) Error() error {
return c.err
}

func (c *UnboundChannel[T]) Send(val T) error {
c.cond.L.Lock()
if c.err != nil {
c.cond.L.Unlock()
return c.err
}
c.values.PushBack(val)
c.cond.L.Unlock()

c.cond.Signal()
return nil
}

func (c *UnboundChannel[T]) Receive() (T, error) {
c.cond.L.Lock()
defer c.cond.L.Unlock()

if c.values.Len() == 0 {
c.cond.Wait()
}

if c.values.Len() == 0 {
var ret T
return ret, c.err
}

ret := c.values.Front().Value.(T)
c.values.Remove(c.values.Front())
return ret, nil
}

func (c *UnboundChannel[T]) Close() {
c.cond.L.Lock()
if c.err != nil {
return
}
c.err = ErrChannelClosed
c.cond.L.Unlock()
c.cond.Broadcast()
}

func (c *UnboundChannel[T]) CloseWithError(err error) {
c.cond.L.Lock()
if c.err != nil {
return
}
c.err = err
c.cond.L.Unlock()
c.cond.Broadcast()
}

+ 28
- 0
utils/time2/duration.go View File

@@ -0,0 +1,28 @@
package time2

import (
"fmt"
"time"
)

type Duration struct {
time.Duration
}

func (d *Duration) Std() time.Duration {
return d.Duration
}

func (d *Duration) Scan(state fmt.ScanState, verb rune) error {
data, err := state.Token(true, nil)
if err != nil {
return err
}

d.Duration, err = time.ParseDuration(string(data))
if err != nil {
return err
}

return nil
}

+ 25
- 0
utils/time2/time2_test.go View File

@@ -0,0 +1,25 @@
package time2

import (
"fmt"
"testing"
"time"

. "github.com/smartystreets/goconvey/convey"
)

func Test_Duration(t *testing.T) {
Convey("从字符串解析", t, func() {
dur := Duration{}
_, err := fmt.Sscanf("10s", "%v", &dur)
So(err, ShouldEqual, nil)
So(dur.Std(), ShouldEqual, 10*time.Second)
})

Convey("包含空白字符", t, func() {
dur := Duration{}
_, err := fmt.Sscanf(" 10s\t\n\r", "%v", &dur)
So(err, ShouldEqual, nil)
So(dur.Std(), ShouldEqual, 10*time.Second)
})
}

Loading…
Cancel
Save