diff --git a/VERSION b/VERSION index d4dfa56..1e66a61 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v0.3.0 \ No newline at end of file +v0.3.1 \ No newline at end of file diff --git a/file_logger.go b/file_logger.go index 1332ce3..74664f8 100644 --- a/file_logger.go +++ b/file_logger.go @@ -8,10 +8,10 @@ import ( "path/filepath" "strings" "sync" + "sync/atomic" "time" "github.com/no-src/log/formatter" - "github.com/no-src/log/internal/cbool" "github.com/no-src/log/level" "github.com/no-src/log/option" ) @@ -35,7 +35,7 @@ type fileLogger struct { in chan logMsg writer *bufio.Writer initialized bool - closed *cbool.CBool + closed atomic.Bool close chan struct{} // the log is closed, and wait to write all the logs mu sync.Mutex // avoid data race for writer date time.Time @@ -61,11 +61,10 @@ func NewFileLoggerWithAutoFlush(lvl level.Level, logDir string, filePrefix strin // NewFileLoggerWithOption get a file logger with option func NewFileLoggerWithOption(opt option.FileLoggerOption) (Logger, error) { logger := &fileLogger{ - opt: opt, - in: make(chan logMsg, 100), - close: make(chan struct{}, 1), - mu: sync.Mutex{}, - closed: cbool.New(false), + opt: opt, + in: make(chan logMsg, 100), + close: make(chan struct{}, 1), + mu: sync.Mutex{}, } // init baseLogger logger.baseLogger.init(logger, opt.Level, true) @@ -76,7 +75,7 @@ func NewFileLoggerWithOption(opt option.FileLoggerOption) (Logger, error) { func (l *fileLogger) Close() error { // stop a new log to write - l.closed.Set(true) + l.closed.Store(true) // send a closed message l.in <- closeLogMsg // wait to receive a close finished message @@ -203,7 +202,7 @@ func (l *fileLogger) startAutoFlush() { delayCheckCount := 10 for { <-time.After(wait) - if l.closed.Get() { + if l.closed.Load() { return } l.mu.Lock() @@ -233,7 +232,7 @@ func (l *fileLogger) Write(p []byte) (n int, err error) { } cp := make([]byte, pLen) copy(cp, p) - if !l.closed.Get() { + if !l.closed.Load() { l.in <- logMsg{ log: cp, closed: false, diff --git a/internal/cbool/cbool.go b/internal/cbool/cbool.go deleted file mode 100644 index 0d12c2b..0000000 --- a/internal/cbool/cbool.go +++ /dev/null @@ -1,35 +0,0 @@ -package cbool - -import ( - "sync/atomic" -) - -// CBool a concurrent safe bool -type CBool struct { - v atomic.Bool -} - -// New create an instance of CBool -func New(v bool) *CBool { - cb := &CBool{} - cb.v.Store(v) - return cb -} - -// Get return the bool value -func (cb *CBool) Get() bool { - return cb.v.Load() -} - -// Set to set the bool value -func (cb *CBool) Set(v bool) { - cb.v.Store(v) -} - -// SetC to set the bool value and return a closed channel -func (cb *CBool) SetC(v bool) <-chan struct{} { - cb.Set(v) - c := make(chan struct{}) - close(c) - return c -} diff --git a/internal/cbool/cbool_test.go b/internal/cbool/cbool_test.go deleted file mode 100644 index 6cfcc92..0000000 --- a/internal/cbool/cbool_test.go +++ /dev/null @@ -1,67 +0,0 @@ -package cbool - -import ( - "sync" - "testing" -) - -func TestCBool(t *testing.T) { - expect := true - cb := New(expect) - actual := cb.Get() - if actual != expect { - t.Errorf("test CBoll New and Get failed, expect:%v, actual:%v", expect, actual) - } - - expect = false - cb.Set(expect) - actual = cb.Get() - if actual != expect { - t.Errorf("test CBoll Set and Get failed, expect:%v, actual:%v", expect, actual) - } - - expect = true - c := cb.SetC(expect) - actual = cb.Get() - if actual != expect { - t.Errorf("test CBoll SetC and Get failed, expect:%v, actual:%v", expect, actual) - } - _, ok := <-c - if ok { - t.Errorf("test CBoll SetC value failed, channel should be closed") - } -} - -func TestCBool_Concurrent(t *testing.T) { - cb := New(false) - wg := sync.WaitGroup{} - count := 10 - wg.Add(count * 3) - for i := 0; i < count; i++ { - go func() { - cb.Get() - wg.Done() - }() - - go func() { - cb.Set(true) - wg.Done() - }() - - go func() { - <-cb.SetC(true) - wg.Done() - }() - } - wg.Wait() -} - -func BenchmarkCBool(b *testing.B) { - b.ReportAllocs() - b.ResetTimer() - cb := New(false) - for i := 0; i < b.N; i++ { - cb.Set(true) - cb.Get() - } -}