diff --git a/container/gset/gset_any_set.go b/container/gset/gset_any_set.go index 760af79e8..e424bc91b 100644 --- a/container/gset/gset_any_set.go +++ b/container/gset/gset_any_set.go @@ -50,7 +50,7 @@ func NewFrom(items interface{}, safe ...bool) *Set { // Iterator iterates the set with given callback function , // if returns true then continue iterating; or false to stop. -func (set *Set) Iterator(f func(v interface{}) bool) *Set { +func (set *Set) Iterator(f func(v interface{}) bool) { set.mu.RLock() defer set.mu.RUnlock() for k, _ := range set.data { @@ -58,11 +58,10 @@ func (set *Set) Iterator(f func(v interface{}) bool) *Set { break } } - return set } // Add adds one or multiple items to the set. -func (set *Set) Add(item ...interface{}) *Set { +func (set *Set) Add(item ...interface{}) { set.mu.Lock() if set.data == nil { set.data = make(map[interface{}]struct{}) @@ -71,54 +70,81 @@ func (set *Set) Add(item ...interface{}) *Set { set.data[v] = struct{}{} } set.mu.Unlock() - return set } -// AddIfNotExistFunc adds the returned value of callback function to the set -// if does not exit in the set. -func (set *Set) AddIfNotExistFunc(item interface{}, f func() interface{}) *Set { +// AddIfNotExist checks whether item exists in the set, +// it adds the item to set and returns true if it does not exists in the set, +// or else it does nothing and returns false. +// +// Note that, if is nil, it does nothing and returns false. +func (set *Set) AddIfNotExist(item interface{}) bool { + if item == nil { + return false + } if !set.Contains(item) { - set.doAddWithLockCheck(item, f()) - } - return set -} - -// AddIfNotExistFuncLock adds the returned value of callback function to the set -// if does not exit in the set. -// -// Note that the callback function is executed in the mutex.Lock of the set. -func (set *Set) AddIfNotExistFuncLock(item interface{}, f func() interface{}) *Set { - if !set.Contains(item) { - set.doAddWithLockCheck(item, f) - } - return set -} - -// doAddWithLockCheck checks whether item exists with mutex.Lock, -// if not exists, it adds item to the set or else just returns the existing value. -// -// If is type of , -// it will be executed with mutex.Lock of the set, -// and its return value will be added to the set. -// -// It returns item successfully added.. -func (set *Set) doAddWithLockCheck(item interface{}, value interface{}) interface{} { - set.mu.Lock() - defer set.mu.Unlock() - if set.data == nil { - set.data = make(map[interface{}]struct{}) - } - if _, ok := set.data[item]; !ok && value != nil { - if f, ok := value.(func() interface{}); ok { - item = f() - } else { - item = value + set.mu.Lock() + defer set.mu.Unlock() + if set.data == nil { + set.data = make(map[interface{}]struct{}) + } + if _, ok := set.data[item]; !ok { + set.data[item] = struct{}{} + return true } } - if item != nil { - set.data[item] = struct{}{} + return false +} + +// AddIfNotExistFunc checks whether item exists in the set, +// it adds the item to set and returns true if it does not exists in the set and +// function returns true, or else it does nothing and returns false. +// +// Note that, if is nil, it does nothing and returns false. The function +// is executed without writing lock. +func (set *Set) AddIfNotExistFunc(item interface{}, f func() bool) bool { + if item == nil { + return false } - return item + if !set.Contains(item) { + if f() { + set.mu.Lock() + defer set.mu.Unlock() + if set.data == nil { + set.data = make(map[interface{}]struct{}) + } + if _, ok := set.data[item]; !ok { + set.data[item] = struct{}{} + return true + } + } + } + return false +} + +// AddIfNotExistFunc checks whether item exists in the set, +// it adds the item to set and returns true if it does not exists in the set and +// function returns true, or else it does nothing and returns false. +// +// Note that, if is nil, it does nothing and returns false. The function +// is executed within writing lock. +func (set *Set) AddIfNotExistFuncLock(item interface{}, f func() bool) bool { + if item == nil { + return false + } + if !set.Contains(item) { + set.mu.Lock() + defer set.mu.Unlock() + if set.data == nil { + set.data = make(map[interface{}]struct{}) + } + if f() { + if _, ok := set.data[item]; !ok { + set.data[item] = struct{}{} + return true + } + } + } + return false } // Contains checks whether the set contains . @@ -133,13 +159,12 @@ func (set *Set) Contains(item interface{}) bool { } // Remove deletes from set. -func (set *Set) Remove(item interface{}) *Set { +func (set *Set) Remove(item interface{}) { set.mu.Lock() if set.data != nil { delete(set.data, item) } set.mu.Unlock() - return set } // Size returns the size of the set. @@ -151,11 +176,10 @@ func (set *Set) Size() int { } // Clear deletes all items of the set. -func (set *Set) Clear() *Set { +func (set *Set) Clear() { set.mu.Lock() set.data = make(map[interface{}]struct{}) set.mu.Unlock() - return set } // Slice returns the a of items of the set as slice. diff --git a/container/gset/gset_int_set.go b/container/gset/gset_int_set.go index e458b7868..2b3b2c0f7 100644 --- a/container/gset/gset_int_set.go +++ b/container/gset/gset_int_set.go @@ -43,7 +43,7 @@ func NewIntSetFrom(items []int, safe ...bool) *IntSet { // Iterator iterates the set with given callback function , // if returns true then continue iterating; or false to stop. -func (set *IntSet) Iterator(f func(v int) bool) *IntSet { +func (set *IntSet) Iterator(f func(v int) bool) { set.mu.RLock() defer set.mu.RUnlock() for k, _ := range set.data { @@ -51,11 +51,10 @@ func (set *IntSet) Iterator(f func(v int) bool) *IntSet { break } } - return set } // Add adds one or multiple items to the set. -func (set *IntSet) Add(item ...int) *IntSet { +func (set *IntSet) Add(item ...int) { set.mu.Lock() if set.data == nil { set.data = make(map[int]struct{}) @@ -64,52 +63,70 @@ func (set *IntSet) Add(item ...int) *IntSet { set.data[v] = struct{}{} } set.mu.Unlock() - return set } -// AddIfNotExistFunc adds the returned value of callback function to the set -// if does not exit in the set. -func (set *IntSet) AddIfNotExistFunc(item int, f func() int) *IntSet { +// AddIfNotExist checks whether item exists in the set, +// it adds the item to set and returns true if it does not exists in the set, +// or else it does nothing and returns false. +// +// Note that, if is nil, it does nothing and returns false. +func (set *IntSet) AddIfNotExist(item int) bool { if !set.Contains(item) { - set.doAddWithLockCheck(item, f()) - } - return set -} - -// AddIfNotExistFuncLock adds the returned value of callback function to the set -// if does not exit in the set. -// -// Note that the callback function is executed in the mutex.Lock of the set. -func (set *IntSet) AddIfNotExistFuncLock(item int, f func() int) *IntSet { - if !set.Contains(item) { - set.doAddWithLockCheck(item, f) - } - return set -} - -// doAddWithLockCheck checks whether item exists with mutex.Lock, -// if not exists, it adds item to the set or else just returns the existing value. -// -// If is type of , -// it will be executed with mutex.Lock of the set, -// and its return value will be added to the set. -// -// It returns item successfully added.. -func (set *IntSet) doAddWithLockCheck(item int, value interface{}) int { - set.mu.Lock() - defer set.mu.Unlock() - if set.data == nil { - set.data = make(map[int]struct{}) - } - if _, ok := set.data[item]; !ok && value != nil { - if f, ok := value.(func() int); ok { - item = f() - } else { - item = value.(int) + set.mu.Lock() + defer set.mu.Unlock() + if set.data == nil { + set.data = make(map[int]struct{}) + } + if _, ok := set.data[item]; !ok { + set.data[item] = struct{}{} + return true } } - set.data[item] = struct{}{} - return item + return false +} + +// AddIfNotExistFunc checks whether item exists in the set, +// it adds the item to set and returns true if it does not exists in the set and +// function returns true, or else it does nothing and returns false. +// +// Note that, the function is executed without writing lock. +func (set *IntSet) AddIfNotExistFunc(item int, f func() bool) bool { + if !set.Contains(item) { + if f() { + set.mu.Lock() + defer set.mu.Unlock() + if set.data == nil { + set.data = make(map[int]struct{}) + } + if _, ok := set.data[item]; !ok { + set.data[item] = struct{}{} + return true + } + } + } + return false +} + +// AddIfNotExistFunc checks whether item exists in the set, +// it adds the item to set and returns true if it does not exists in the set and +// function returns true, or else it does nothing and returns false. +// +// Note that, the function is executed without writing lock. +func (set *IntSet) AddIfNotExistFuncLock(item int, f func() bool) bool { + if !set.Contains(item) { + set.mu.Lock() + defer set.mu.Unlock() + if set.data == nil { + set.data = make(map[int]struct{}) + } + if f() { + if _, ok := set.data[item]; !ok { + set.data[item] = struct{}{} + return true + } + } + } + return false } // Contains checks whether the set contains . @@ -124,13 +141,12 @@ func (set *IntSet) Contains(item int) bool { } // Remove deletes from set. -func (set *IntSet) Remove(item int) *IntSet { +func (set *IntSet) Remove(item int) { set.mu.Lock() if set.data != nil { delete(set.data, item) } set.mu.Unlock() - return set } // Size returns the size of the set. @@ -142,11 +158,10 @@ func (set *IntSet) Size() int { } // Clear deletes all items of the set. -func (set *IntSet) Clear() *IntSet { +func (set *IntSet) Clear() { set.mu.Lock() set.data = make(map[int]struct{}) set.mu.Unlock() - return set } // Slice returns the a of items of the set as slice. diff --git a/container/gset/gset_str_set.go b/container/gset/gset_str_set.go index e7fd5f3ad..04c44196c 100644 --- a/container/gset/gset_str_set.go +++ b/container/gset/gset_str_set.go @@ -44,7 +44,7 @@ func NewStrSetFrom(items []string, safe ...bool) *StrSet { // Iterator iterates the set with given callback function , // if returns true then continue iterating; or false to stop. -func (set *StrSet) Iterator(f func(v string) bool) *StrSet { +func (set *StrSet) Iterator(f func(v string) bool) { set.mu.RLock() defer set.mu.RUnlock() for k, _ := range set.data { @@ -52,11 +52,10 @@ func (set *StrSet) Iterator(f func(v string) bool) *StrSet { break } } - return set } // Add adds one or multiple items to the set. -func (set *StrSet) Add(item ...string) *StrSet { +func (set *StrSet) Add(item ...string) { set.mu.Lock() if set.data == nil { set.data = make(map[string]struct{}) @@ -65,54 +64,68 @@ func (set *StrSet) Add(item ...string) *StrSet { set.data[v] = struct{}{} } set.mu.Unlock() - return set } -// AddIfNotExistFunc adds the returned value of callback function to the set -// if does not exit in the set. -func (set *StrSet) AddIfNotExistFunc(item string, f func() string) *StrSet { +// AddIfNotExist checks whether item exists in the set, +// it adds the item to set and returns true if it does not exists in the set, +// or else it does nothing and returns false. +func (set *StrSet) AddIfNotExist(item string) bool { if !set.Contains(item) { - set.doAddWithLockCheck(item, f()) - } - return set -} - -// AddIfNotExistFuncLock adds the returned value of callback function to the set -// if does not exit in the set. -// -// Note that the callback function is executed in the mutex.Lock of the set. -func (set *StrSet) AddIfNotExistFuncLock(item string, f func() string) *StrSet { - if !set.Contains(item) { - set.doAddWithLockCheck(item, f) - } - return set -} - -// doAddWithLockCheck checks whether item exists with mutex.Lock, -// if not exists, it adds item to the set or else just returns the existing value. -// -// If is type of , -// it will be executed with mutex.Lock of the set, -// and its return value will be added to the set. -// -// It returns item successfully added.. -func (set *StrSet) doAddWithLockCheck(item string, value interface{}) string { - set.mu.Lock() - defer set.mu.Unlock() - if set.data == nil { - set.data = make(map[string]struct{}) - } - if _, ok := set.data[item]; !ok && value != nil { - if f, ok := value.(func() string); ok { - item = f() - } else { - item = value.(string) + set.mu.Lock() + defer set.mu.Unlock() + if set.data == nil { + set.data = make(map[string]struct{}) + } + if _, ok := set.data[item]; !ok { + set.data[item] = struct{}{} + return true } } - if item != "" { - set.data[item] = struct{}{} + return false +} + +// AddIfNotExistFunc checks whether item exists in the set, +// it adds the item to set and returns true if it does not exists in the set and +// function returns true, or else it does nothing and returns false. +// +// Note that, the function is executed without writing lock. +func (set *StrSet) AddIfNotExistFunc(item string, f func() bool) bool { + if !set.Contains(item) { + if f() { + set.mu.Lock() + defer set.mu.Unlock() + if set.data == nil { + set.data = make(map[string]struct{}) + } + if _, ok := set.data[item]; !ok { + set.data[item] = struct{}{} + return true + } + } } - return item + return false +} + +// AddIfNotExistFunc checks whether item exists in the set, +// it adds the item to set and returns true if it does not exists in the set and +// function returns true, or else it does nothing and returns false. +// +// Note that, the function is executed without writing lock. +func (set *StrSet) AddIfNotExistFuncLock(item string, f func() bool) bool { + if !set.Contains(item) { + set.mu.Lock() + defer set.mu.Unlock() + if set.data == nil { + set.data = make(map[string]struct{}) + } + if f() { + if _, ok := set.data[item]; !ok { + set.data[item] = struct{}{} + return true + } + } + } + return false } // Contains checks whether the set contains . @@ -127,13 +140,12 @@ func (set *StrSet) Contains(item string) bool { } // Remove deletes from set. -func (set *StrSet) Remove(item string) *StrSet { +func (set *StrSet) Remove(item string) { set.mu.Lock() if set.data != nil { delete(set.data, item) } set.mu.Unlock() - return set } // Size returns the size of the set. @@ -145,11 +157,10 @@ func (set *StrSet) Size() int { } // Clear deletes all items of the set. -func (set *StrSet) Clear() *StrSet { +func (set *StrSet) Clear() { set.mu.Lock() set.data = make(map[string]struct{}) set.mu.Unlock() - return set } // Slice returns the a of items of the set as slice. diff --git a/container/gset/gset_z_unit_any_test.go b/container/gset/gset_z_unit_any_test.go index ac5ecea73..64db0e4ad 100644 --- a/container/gset/gset_z_unit_any_test.go +++ b/container/gset/gset_z_unit_any_test.go @@ -13,6 +13,8 @@ import ( "github.com/gogf/gf/frame/g" "github.com/gogf/gf/util/gconv" "strings" + "sync" + "time" "github.com/gogf/gf/container/garray" "github.com/gogf/gf/container/gset" @@ -24,7 +26,7 @@ import ( func TestSet_Var(t *testing.T) { gtest.C(t, func(t *gtest.T) { var s gset.Set - s.Add(1).Add(1).Add(2) + s.Add(1, 1, 2) s.Add([]interface{}{3, 4}...) t.Assert(s.Size(), 4) t.AssertIN(1, s.Slice()) @@ -44,7 +46,7 @@ func TestSet_Var(t *testing.T) { func TestSet_New(t *testing.T) { gtest.C(t, func(t *gtest.T) { s := gset.New() - s.Add(1).Add(1).Add(2) + s.Add(1, 1, 2) s.Add([]interface{}{3, 4}...) t.Assert(s.Size(), 4) t.AssertIN(1, s.Slice()) @@ -64,7 +66,7 @@ func TestSet_New(t *testing.T) { func TestSet_Basic(t *testing.T) { gtest.C(t, func(t *gtest.T) { s := gset.NewSet() - s.Add(1).Add(1).Add(2) + s.Add(1, 1, 2) s.Add([]interface{}{3, 4}...) t.Assert(s.Size(), 4) t.AssertIN(1, s.Slice()) @@ -84,7 +86,7 @@ func TestSet_Basic(t *testing.T) { func TestSet_Iterator(t *testing.T) { gtest.C(t, func(t *gtest.T) { s := gset.NewSet() - s.Add(1).Add(2).Add(3) + s.Add(1, 2, 3) t.Assert(s.Size(), 3) a1 := garray.New(true) @@ -105,7 +107,7 @@ func TestSet_Iterator(t *testing.T) { func TestSet_LockFunc(t *testing.T) { gtest.C(t, func(t *gtest.T) { s := gset.NewSet() - s.Add(1).Add(2).Add(3) + s.Add(1, 2, 3) t.Assert(s.Size(), 3) s.LockFunc(func(m map[interface{}]struct{}) { delete(m, 1) @@ -125,9 +127,9 @@ func TestSet_Equal(t *testing.T) { s1 := gset.NewSet() s2 := gset.NewSet() s3 := gset.NewSet() - s1.Add(1).Add(2).Add(3) - s2.Add(1).Add(2).Add(3) - s3.Add(1).Add(2).Add(3).Add(4) + s1.Add(1, 2, 3) + s2.Add(1, 2, 3) + s3.Add(1, 2, 3, 4) t.Assert(s1.Equal(s2), true) t.Assert(s1.Equal(s3), false) }) @@ -138,9 +140,9 @@ func TestSet_IsSubsetOf(t *testing.T) { s1 := gset.NewSet() s2 := gset.NewSet() s3 := gset.NewSet() - s1.Add(1).Add(2) - s2.Add(1).Add(2).Add(3) - s3.Add(1).Add(2).Add(3).Add(4) + s1.Add(1, 2) + s2.Add(1, 2, 3) + s3.Add(1, 2, 3, 4) t.Assert(s1.IsSubsetOf(s2), true) t.Assert(s2.IsSubsetOf(s3), true) t.Assert(s1.IsSubsetOf(s3), true) @@ -153,8 +155,8 @@ func TestSet_Union(t *testing.T) { gtest.C(t, func(t *gtest.T) { s1 := gset.NewSet() s2 := gset.NewSet() - s1.Add(1).Add(2) - s2.Add(3).Add(4) + s1.Add(1, 2) + s2.Add(3, 4) s3 := s1.Union(s2) t.Assert(s3.Contains(1), true) t.Assert(s3.Contains(2), true) @@ -167,8 +169,8 @@ func TestSet_Diff(t *testing.T) { gtest.C(t, func(t *gtest.T) { s1 := gset.NewSet() s2 := gset.NewSet() - s1.Add(1).Add(2).Add(3) - s2.Add(3).Add(4).Add(5) + s1.Add(1, 2, 3) + s2.Add(3, 4, 5) s3 := s1.Diff(s2) t.Assert(s3.Contains(1), true) t.Assert(s3.Contains(2), true) @@ -181,8 +183,8 @@ func TestSet_Intersect(t *testing.T) { gtest.C(t, func(t *gtest.T) { s1 := gset.NewSet() s2 := gset.NewSet() - s1.Add(1).Add(2).Add(3) - s2.Add(3).Add(4).Add(5) + s1.Add(1, 2, 3) + s2.Add(3, 4, 5) s3 := s1.Intersect(s2) t.Assert(s3.Contains(1), false) t.Assert(s3.Contains(2), false) @@ -195,8 +197,8 @@ func TestSet_Complement(t *testing.T) { gtest.C(t, func(t *gtest.T) { s1 := gset.NewSet() s2 := gset.NewSet() - s1.Add(1).Add(2).Add(3) - s2.Add(3).Add(4).Add(5) + s1.Add(1, 2, 3) + s2.Add(3, 4, 5) s3 := s1.Complement(s2) t.Assert(s3.Contains(1), false) t.Assert(s3.Contains(2), false) @@ -223,9 +225,9 @@ func TestNewFrom(t *testing.T) { func TestNew(t *testing.T) { gtest.C(t, func(t *gtest.T) { s1 := gset.New() - s1.Add("a").Add(2) + s1.Add("a", 2) s2 := gset.New(true) - s2.Add("b").Add(3) + s2.Add("b", 3) t.Assert(s1.Contains("a"), true) }) @@ -234,13 +236,13 @@ func TestNew(t *testing.T) { func TestSet_Join(t *testing.T) { gtest.C(t, func(t *gtest.T) { s1 := gset.New(true) - s1.Add("a").Add("a1").Add("b").Add("c") + s1.Add("a", "a1", "b", "c") str1 := s1.Join(",") t.Assert(strings.Contains(str1, "a1"), true) }) gtest.C(t, func(t *gtest.T) { s1 := gset.New(true) - s1.Add("a").Add(`"b"`).Add(`\c`) + s1.Add("a", `"b"`, `\c`) str1 := s1.Join(",") t.Assert(strings.Contains(str1, `"b"`), true) t.Assert(strings.Contains(str1, `\c`), true) @@ -251,7 +253,7 @@ func TestSet_Join(t *testing.T) { func TestSet_String(t *testing.T) { gtest.C(t, func(t *gtest.T) { s1 := gset.New(true) - s1.Add("a").Add("a2").Add("b").Add("c") + s1.Add("a", "a2", "b", "c") str1 := s1.String() t.Assert(strings.Contains(str1, "["), true) t.Assert(strings.Contains(str1, "]"), true) @@ -263,8 +265,8 @@ func TestSet_Merge(t *testing.T) { gtest.C(t, func(t *gtest.T) { s1 := gset.New(true) s2 := gset.New(true) - s1.Add("a").Add("a2").Add("b").Add("c") - s2.Add("b").Add("b1").Add("e").Add("f") + s1.Add("a", "a2", "b", "c") + s2.Add("b", "b1", "e", "f") ss := s1.Merge(s2) t.Assert(ss.Contains("a2"), true) t.Assert(ss.Contains("b1"), true) @@ -275,7 +277,7 @@ func TestSet_Merge(t *testing.T) { func TestSet_Sum(t *testing.T) { gtest.C(t, func(t *gtest.T) { s1 := gset.New(true) - s1.Add(1).Add(2).Add(3).Add(4) + s1.Add(1, 2, 3, 4) t.Assert(s1.Sum(), int(10)) }) @@ -284,7 +286,7 @@ func TestSet_Sum(t *testing.T) { func TestSet_Pop(t *testing.T) { gtest.C(t, func(t *gtest.T) { s := gset.New(true) - s.Add(1).Add(2).Add(3).Add(4) + s.Add(1, 2, 3, 4) t.Assert(s.Size(), 4) t.AssertIN(s.Pop(), []int{1, 2, 3, 4}) t.Assert(s.Size(), 3) @@ -294,7 +296,7 @@ func TestSet_Pop(t *testing.T) { func TestSet_Pops(t *testing.T) { gtest.C(t, func(t *gtest.T) { s := gset.New(true) - s.Add(1).Add(2).Add(3).Add(4) + s.Add(1, 2, 3, 4) t.Assert(s.Size(), 4) t.Assert(s.Pops(0), nil) t.AssertIN(s.Pops(1), []int{1, 2, 3, 4}) @@ -344,43 +346,71 @@ func TestSet_Json(t *testing.T) { }) } +func TestSet_AddIfNotExist(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + s := gset.New(true) + s.Add(1) + t.Assert(s.Contains(1), true) + t.Assert(s.AddIfNotExist(1), false) + t.Assert(s.AddIfNotExist(2), true) + t.Assert(s.Contains(2), true) + t.Assert(s.AddIfNotExist(2), false) + t.Assert(s.Contains(2), true) + }) +} + func TestSet_AddIfNotExistFunc(t *testing.T) { gtest.C(t, func(t *gtest.T) { s := gset.New(true) s.Add(1) t.Assert(s.Contains(1), true) t.Assert(s.Contains(2), false) - - s.AddIfNotExistFunc(2, func() interface{} { - return 3 - }) + t.Assert(s.AddIfNotExistFunc(2, func() bool { return false }), false) t.Assert(s.Contains(2), false) - t.Assert(s.Contains(3), true) - - s.AddIfNotExistFunc(3, func() interface{} { - return 4 - }) - t.Assert(s.Contains(3), true) - t.Assert(s.Contains(4), false) + t.Assert(s.AddIfNotExistFunc(2, func() bool { return true }), true) + t.Assert(s.Contains(2), true) + t.Assert(s.AddIfNotExistFunc(2, func() bool { return true }), false) + t.Assert(s.Contains(2), true) }) - gtest.C(t, func(t *gtest.T) { s := gset.New(true) + wg := sync.WaitGroup{} + wg.Add(1) + go func() { + defer wg.Done() + r := s.AddIfNotExistFunc(1, func() bool { + time.Sleep(100 * time.Millisecond) + return true + }) + t.Assert(r, false) + }() s.Add(1) - t.Assert(s.Contains(1), true) - t.Assert(s.Contains(2), false) + wg.Wait() + }) +} - s.AddIfNotExistFuncLock(2, func() interface{} { - return 3 - }) - t.Assert(s.Contains(2), false) - t.Assert(s.Contains(3), true) - - s.AddIfNotExistFuncLock(3, func() interface{} { - return 4 - }) - t.Assert(s.Contains(3), true) - t.Assert(s.Contains(4), false) +func TestSet_AddIfNotExistFuncLock(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + s := gset.New(true) + wg := sync.WaitGroup{} + wg.Add(2) + go func() { + defer wg.Done() + r := s.AddIfNotExistFuncLock(1, func() bool { + time.Sleep(500 * time.Millisecond) + return true + }) + t.Assert(r, true) + }() + time.Sleep(100 * time.Millisecond) + go func() { + defer wg.Done() + r := s.AddIfNotExistFuncLock(1, func() bool { + return true + }) + t.Assert(r, false) + }() + wg.Wait() }) } diff --git a/container/gset/gset_z_unit_int_test.go b/container/gset/gset_z_unit_int_test.go index 6180f6228..a749fa27d 100644 --- a/container/gset/gset_z_unit_int_test.go +++ b/container/gset/gset_z_unit_int_test.go @@ -13,7 +13,9 @@ import ( "github.com/gogf/gf/frame/g" "github.com/gogf/gf/util/gconv" "strings" + "sync" "testing" + "time" "github.com/gogf/gf/container/garray" "github.com/gogf/gf/container/gset" @@ -23,7 +25,7 @@ import ( func TestIntSet_Var(t *testing.T) { gtest.C(t, func(t *gtest.T) { var s gset.IntSet - s.Add(1).Add(1).Add(2) + s.Add(1, 1, 2) s.Add([]int{3, 4}...) t.Assert(s.Size(), 4) t.AssertIN(1, s.Slice()) @@ -43,7 +45,7 @@ func TestIntSet_Var(t *testing.T) { func TestIntSet_Basic(t *testing.T) { gtest.C(t, func(t *gtest.T) { s := gset.NewIntSet() - s.Add(1).Add(1).Add(2) + s.Add(1, 1, 2) s.Add([]int{3, 4}...) t.Assert(s.Size(), 4) t.AssertIN(1, s.Slice()) @@ -63,7 +65,7 @@ func TestIntSet_Basic(t *testing.T) { func TestIntSet_Iterator(t *testing.T) { gtest.C(t, func(t *gtest.T) { s := gset.NewIntSet() - s.Add(1).Add(2).Add(3) + s.Add(1, 2, 3) t.Assert(s.Size(), 3) a1 := garray.New(true) @@ -84,7 +86,7 @@ func TestIntSet_Iterator(t *testing.T) { func TestIntSet_LockFunc(t *testing.T) { gtest.C(t, func(t *gtest.T) { s := gset.NewIntSet() - s.Add(1).Add(2).Add(3) + s.Add(1, 2, 3) t.Assert(s.Size(), 3) s.LockFunc(func(m map[int]struct{}) { delete(m, 1) @@ -104,9 +106,9 @@ func TestIntSet_Equal(t *testing.T) { s1 := gset.NewIntSet() s2 := gset.NewIntSet() s3 := gset.NewIntSet() - s1.Add(1).Add(2).Add(3) - s2.Add(1).Add(2).Add(3) - s3.Add(1).Add(2).Add(3).Add(4) + s1.Add(1, 2, 3) + s2.Add(1, 2, 3) + s3.Add(1, 2, 3, 4) t.Assert(s1.Equal(s2), true) t.Assert(s1.Equal(s3), false) }) @@ -117,9 +119,9 @@ func TestIntSet_IsSubsetOf(t *testing.T) { s1 := gset.NewIntSet() s2 := gset.NewIntSet() s3 := gset.NewIntSet() - s1.Add(1).Add(2) - s2.Add(1).Add(2).Add(3) - s3.Add(1).Add(2).Add(3).Add(4) + s1.Add(1, 2) + s2.Add(1, 2, 3) + s3.Add(1, 2, 3, 4) t.Assert(s1.IsSubsetOf(s2), true) t.Assert(s2.IsSubsetOf(s3), true) t.Assert(s1.IsSubsetOf(s3), true) @@ -132,8 +134,8 @@ func TestIntSet_Union(t *testing.T) { gtest.C(t, func(t *gtest.T) { s1 := gset.NewIntSet() s2 := gset.NewIntSet() - s1.Add(1).Add(2) - s2.Add(3).Add(4) + s1.Add(1, 2) + s2.Add(3, 4) s3 := s1.Union(s2) t.Assert(s3.Contains(1), true) t.Assert(s3.Contains(2), true) @@ -146,8 +148,8 @@ func TestIntSet_Diff(t *testing.T) { gtest.C(t, func(t *gtest.T) { s1 := gset.NewIntSet() s2 := gset.NewIntSet() - s1.Add(1).Add(2).Add(3) - s2.Add(3).Add(4).Add(5) + s1.Add(1, 2, 3) + s2.Add(3, 4, 5) s3 := s1.Diff(s2) t.Assert(s3.Contains(1), true) t.Assert(s3.Contains(2), true) @@ -160,8 +162,8 @@ func TestIntSet_Intersect(t *testing.T) { gtest.C(t, func(t *gtest.T) { s1 := gset.NewIntSet() s2 := gset.NewIntSet() - s1.Add(1).Add(2).Add(3) - s2.Add(3).Add(4).Add(5) + s1.Add(1, 2, 3) + s2.Add(3, 4, 5) s3 := s1.Intersect(s2) t.Assert(s3.Contains(1), false) t.Assert(s3.Contains(2), false) @@ -174,8 +176,8 @@ func TestIntSet_Complement(t *testing.T) { gtest.C(t, func(t *gtest.T) { s1 := gset.NewIntSet() s2 := gset.NewIntSet() - s1.Add(1).Add(2).Add(3) - s2.Add(3).Add(4).Add(5) + s1.Add(1, 2, 3) + s2.Add(3, 4, 5) s3 := s1.Complement(s2) t.Assert(s3.Contains(1), false) t.Assert(s3.Contains(2), false) @@ -187,7 +189,7 @@ func TestIntSet_Complement(t *testing.T) { func TestIntSet_Size(t *testing.T) { gtest.C(t, func(t *gtest.T) { s1 := gset.NewIntSet(true) - s1.Add(1).Add(2).Add(3) + s1.Add(1, 2, 3) t.Assert(s1.Size(), 3) }) @@ -198,8 +200,8 @@ func TestIntSet_Merge(t *testing.T) { gtest.C(t, func(t *gtest.T) { s1 := gset.NewIntSet() s2 := gset.NewIntSet() - s1.Add(1).Add(2).Add(3) - s2.Add(3).Add(4).Add(5) + s1.Add(1, 2, 3) + s2.Add(3, 4, 5) s3 := s1.Merge(s2) t.Assert(s3.Contains(1), true) t.Assert(s3.Contains(5), true) @@ -210,7 +212,7 @@ func TestIntSet_Merge(t *testing.T) { func TestIntSet_Join(t *testing.T) { gtest.C(t, func(t *gtest.T) { s1 := gset.NewIntSet() - s1.Add(1).Add(2).Add(3) + s1.Add(1, 2, 3) s3 := s1.Join(",") t.Assert(strings.Contains(s3, "1"), true) t.Assert(strings.Contains(s3, "2"), true) @@ -221,7 +223,7 @@ func TestIntSet_Join(t *testing.T) { func TestIntSet_String(t *testing.T) { gtest.C(t, func(t *gtest.T) { s1 := gset.NewIntSet() - s1.Add(1).Add(2).Add(3) + s1.Add(1, 2, 3) s3 := s1.String() t.Assert(strings.Contains(s3, "["), true) t.Assert(strings.Contains(s3, "]"), true) @@ -234,9 +236,9 @@ func TestIntSet_String(t *testing.T) { func TestIntSet_Sum(t *testing.T) { gtest.C(t, func(t *gtest.T) { s1 := gset.NewIntSet() - s1.Add(1).Add(2).Add(3) + s1.Add(1, 2, 3) s2 := gset.NewIntSet() - s2.Add(5).Add(6).Add(7) + s2.Add(5, 6, 7) t.Assert(s2.Sum(), 18) }) @@ -246,7 +248,7 @@ func TestIntSet_Sum(t *testing.T) { func TestIntSet_Pop(t *testing.T) { gtest.C(t, func(t *gtest.T) { s := gset.NewIntSet() - s.Add(4).Add(2).Add(3) + s.Add(4, 2, 3) t.Assert(s.Size(), 3) t.AssertIN(s.Pop(), []int{4, 2, 3}) t.AssertIN(s.Pop(), []int{4, 2, 3}) @@ -257,7 +259,7 @@ func TestIntSet_Pop(t *testing.T) { func TestIntSet_Pops(t *testing.T) { gtest.C(t, func(t *gtest.T) { s := gset.NewIntSet() - s.Add(1).Add(4).Add(2).Add(3) + s.Add(1, 4, 2, 3) t.Assert(s.Size(), 4) t.Assert(s.Pops(0), nil) t.AssertIN(s.Pops(1), []int{1, 4, 2, 3}) @@ -278,6 +280,74 @@ func TestIntSet_Pops(t *testing.T) { }) } +func TestIntSet_AddIfNotExist(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + s := gset.NewIntSet(true) + s.Add(1) + t.Assert(s.Contains(1), true) + t.Assert(s.AddIfNotExist(1), false) + t.Assert(s.AddIfNotExist(2), true) + t.Assert(s.Contains(2), true) + t.Assert(s.AddIfNotExist(2), false) + t.Assert(s.Contains(2), true) + }) +} + +func TestIntSet_AddIfNotExistFunc(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + s := gset.NewIntSet(true) + s.Add(1) + t.Assert(s.Contains(1), true) + t.Assert(s.Contains(2), false) + t.Assert(s.AddIfNotExistFunc(2, func() bool { return false }), false) + t.Assert(s.Contains(2), false) + t.Assert(s.AddIfNotExistFunc(2, func() bool { return true }), true) + t.Assert(s.Contains(2), true) + t.Assert(s.AddIfNotExistFunc(2, func() bool { return true }), false) + t.Assert(s.Contains(2), true) + }) + gtest.C(t, func(t *gtest.T) { + s := gset.NewIntSet(true) + wg := sync.WaitGroup{} + wg.Add(1) + go func() { + defer wg.Done() + r := s.AddIfNotExistFunc(1, func() bool { + time.Sleep(100 * time.Millisecond) + return true + }) + t.Assert(r, false) + }() + s.Add(1) + wg.Wait() + }) +} + +func TestIntSet_AddIfNotExistFuncLock(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + s := gset.NewIntSet(true) + wg := sync.WaitGroup{} + wg.Add(2) + go func() { + defer wg.Done() + r := s.AddIfNotExistFuncLock(1, func() bool { + time.Sleep(500 * time.Millisecond) + return true + }) + t.Assert(r, true) + }() + time.Sleep(100 * time.Millisecond) + go func() { + defer wg.Done() + r := s.AddIfNotExistFuncLock(1, func() bool { + return true + }) + t.Assert(r, false) + }() + wg.Wait() + }) +} + func TestIntSet_Json(t *testing.T) { gtest.C(t, func(t *gtest.T) { s1 := []int{1, 3, 2, 4} @@ -307,46 +377,6 @@ func TestIntSet_Json(t *testing.T) { }) } -func TestIntSet_AddIfNotExistFunc(t *testing.T) { - gtest.C(t, func(t *gtest.T) { - s := gset.NewIntSet(true) - s.Add(1) - t.Assert(s.Contains(1), true) - t.Assert(s.Contains(2), false) - - s.AddIfNotExistFunc(2, func() int { - return 3 - }) - t.Assert(s.Contains(2), false) - t.Assert(s.Contains(3), true) - - s.AddIfNotExistFunc(3, func() int { - return 4 - }) - t.Assert(s.Contains(3), true) - t.Assert(s.Contains(4), false) - }) - - gtest.C(t, func(t *gtest.T) { - s := gset.NewIntSet(true) - s.Add(1) - t.Assert(s.Contains(1), true) - t.Assert(s.Contains(2), false) - - s.AddIfNotExistFuncLock(2, func() int { - return 3 - }) - t.Assert(s.Contains(2), false) - t.Assert(s.Contains(3), true) - - s.AddIfNotExistFuncLock(3, func() int { - return 4 - }) - t.Assert(s.Contains(3), true) - t.Assert(s.Contains(4), false) - }) -} - func TestIntSet_UnmarshalValue(t *testing.T) { type V struct { Name string diff --git a/container/gset/gset_z_unit_str_test.go b/container/gset/gset_z_unit_str_test.go index 14acabdfa..ce654c3fa 100644 --- a/container/gset/gset_z_unit_str_test.go +++ b/container/gset/gset_z_unit_str_test.go @@ -13,7 +13,9 @@ import ( "github.com/gogf/gf/frame/g" "github.com/gogf/gf/util/gconv" "strings" + "sync" "testing" + "time" "github.com/gogf/gf/container/garray" "github.com/gogf/gf/container/gset" @@ -23,7 +25,7 @@ import ( func TestStrSet_Var(t *testing.T) { gtest.C(t, func(t *gtest.T) { var s gset.StrSet - s.Add("1").Add("1").Add("2") + s.Add("1", "1", "2") s.Add([]string{"3", "4"}...) t.Assert(s.Size(), 4) t.AssertIN("1", s.Slice()) @@ -43,7 +45,7 @@ func TestStrSet_Var(t *testing.T) { func TestStrSet_Basic(t *testing.T) { gtest.C(t, func(t *gtest.T) { s := gset.NewStrSet() - s.Add("1").Add("1").Add("2") + s.Add("1", "1", "2") s.Add([]string{"3", "4"}...) t.Assert(s.Size(), 4) t.AssertIN("1", s.Slice()) @@ -63,7 +65,7 @@ func TestStrSet_Basic(t *testing.T) { func TestStrSet_Iterator(t *testing.T) { gtest.C(t, func(t *gtest.T) { s := gset.NewStrSet() - s.Add("1").Add("2").Add("3") + s.Add("1", "2", "3") t.Assert(s.Size(), 3) a1 := garray.New(true) @@ -84,7 +86,7 @@ func TestStrSet_Iterator(t *testing.T) { func TestStrSet_LockFunc(t *testing.T) { gtest.C(t, func(t *gtest.T) { s := gset.NewStrSet() - s.Add("1").Add("2").Add("3") + s.Add("1", "2", "3") t.Assert(s.Size(), 3) s.LockFunc(func(m map[string]struct{}) { delete(m, "1") @@ -104,9 +106,9 @@ func TestStrSet_Equal(t *testing.T) { s1 := gset.NewStrSet() s2 := gset.NewStrSet() s3 := gset.NewStrSet() - s1.Add("1").Add("2").Add("3") - s2.Add("1").Add("2").Add("3") - s3.Add("1").Add("2").Add("3").Add("4") + s1.Add("1", "2", "3") + s2.Add("1", "2", "3") + s3.Add("1", "2", "3", "4") t.Assert(s1.Equal(s2), true) t.Assert(s1.Equal(s3), false) }) @@ -117,9 +119,9 @@ func TestStrSet_IsSubsetOf(t *testing.T) { s1 := gset.NewStrSet() s2 := gset.NewStrSet() s3 := gset.NewStrSet() - s1.Add("1").Add("2") - s2.Add("1").Add("2").Add("3") - s3.Add("1").Add("2").Add("3").Add("4") + s1.Add("1", "2") + s2.Add("1", "2", "3") + s3.Add("1", "2", "3", "4") t.Assert(s1.IsSubsetOf(s2), true) t.Assert(s2.IsSubsetOf(s3), true) t.Assert(s1.IsSubsetOf(s3), true) @@ -132,8 +134,8 @@ func TestStrSet_Union(t *testing.T) { gtest.C(t, func(t *gtest.T) { s1 := gset.NewStrSet() s2 := gset.NewStrSet() - s1.Add("1").Add("2") - s2.Add("3").Add("4") + s1.Add("1", "2") + s2.Add("3", "4") s3 := s1.Union(s2) t.Assert(s3.Contains("1"), true) t.Assert(s3.Contains("2"), true) @@ -146,8 +148,8 @@ func TestStrSet_Diff(t *testing.T) { gtest.C(t, func(t *gtest.T) { s1 := gset.NewStrSet() s2 := gset.NewStrSet() - s1.Add("1").Add("2").Add("3") - s2.Add("3").Add("4").Add("5") + s1.Add("1", "2", "3") + s2.Add("3", "4", "5") s3 := s1.Diff(s2) t.Assert(s3.Contains("1"), true) t.Assert(s3.Contains("2"), true) @@ -160,8 +162,8 @@ func TestStrSet_Intersect(t *testing.T) { gtest.C(t, func(t *gtest.T) { s1 := gset.NewStrSet() s2 := gset.NewStrSet() - s1.Add("1").Add("2").Add("3") - s2.Add("3").Add("4").Add("5") + s1.Add("1", "2", "3") + s2.Add("3", "4", "5") s3 := s1.Intersect(s2) t.Assert(s3.Contains("1"), false) t.Assert(s3.Contains("2"), false) @@ -174,8 +176,8 @@ func TestStrSet_Complement(t *testing.T) { gtest.C(t, func(t *gtest.T) { s1 := gset.NewStrSet() s2 := gset.NewStrSet() - s1.Add("1").Add("2").Add("3") - s2.Add("3").Add("4").Add("5") + s1.Add("1", "2", "3") + s2.Add("3", "4", "5") s3 := s1.Complement(s2) t.Assert(s3.Contains("1"), false) t.Assert(s3.Contains("2"), false) @@ -199,8 +201,8 @@ func TestStrSet_Merge(t *testing.T) { gtest.C(t, func(t *gtest.T) { s1 := gset.NewStrSet() s2 := gset.NewStrSet() - s1.Add("1").Add("2").Add("3") - s2.Add("3").Add("4").Add("5") + s1.Add("1", "2", "3") + s2.Add("3", "4", "5") s3 := s1.Merge(s2) t.Assert(s3.Contains("1"), true) t.Assert(s3.Contains("6"), false) @@ -227,7 +229,7 @@ func TestStrSet_Join(t *testing.T) { gtest.C(t, func(t *gtest.T) { s1 := gset.NewStrSet() - s1.Add("a").Add(`"b"`).Add(`\c`) + s1.Add("a", `"b"`, `\c`) str1 := s1.Join(",") t.Assert(strings.Contains(str1, `"b"`), true) t.Assert(strings.Contains(str1, `\c`), true) @@ -245,7 +247,7 @@ func TestStrSet_String(t *testing.T) { gtest.C(t, func(t *gtest.T) { s1 := gset.New(true) - s1.Add("a").Add("a2").Add("b").Add("c") + s1.Add("a", "a2", "b", "c") str1 := s1.String() t.Assert(strings.Contains(str1, "["), true) t.Assert(strings.Contains(str1, "]"), true) @@ -273,7 +275,7 @@ func TestStrSet_Size(t *testing.T) { func TestStrSet_Remove(t *testing.T) { gtest.C(t, func(t *gtest.T) { s1 := gset.NewStrSetFrom([]string{"a", "b", "c"}, true) - s1 = s1.Remove("b") + s1.Remove("b") t.Assert(s1.Contains("b"), false) t.Assert(s1.Contains("c"), true) }) @@ -314,6 +316,74 @@ func TestStrSet_Pops(t *testing.T) { }) } +func TestStrSet_AddIfNotExist(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + s := gset.NewStrSet(true) + s.Add("1") + t.Assert(s.Contains("1"), true) + t.Assert(s.AddIfNotExist("1"), false) + t.Assert(s.AddIfNotExist("2"), true) + t.Assert(s.Contains("2"), true) + t.Assert(s.AddIfNotExist("2"), false) + t.Assert(s.Contains("2"), true) + }) +} + +func TestStrSet_AddIfNotExistFunc(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + s := gset.NewStrSet(true) + s.Add("1") + t.Assert(s.Contains("1"), true) + t.Assert(s.Contains("2"), false) + t.Assert(s.AddIfNotExistFunc("2", func() bool { return false }), false) + t.Assert(s.Contains("2"), false) + t.Assert(s.AddIfNotExistFunc("2", func() bool { return true }), true) + t.Assert(s.Contains("2"), true) + t.Assert(s.AddIfNotExistFunc("2", func() bool { return true }), false) + t.Assert(s.Contains("2"), true) + }) + gtest.C(t, func(t *gtest.T) { + s := gset.NewStrSet(true) + wg := sync.WaitGroup{} + wg.Add(1) + go func() { + defer wg.Done() + r := s.AddIfNotExistFunc("1", func() bool { + time.Sleep(100 * time.Millisecond) + return true + }) + t.Assert(r, false) + }() + s.Add("1") + wg.Wait() + }) +} + +func TestStrSet_AddIfNotExistFuncLock(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + s := gset.NewStrSet(true) + wg := sync.WaitGroup{} + wg.Add(2) + go func() { + defer wg.Done() + r := s.AddIfNotExistFuncLock("1", func() bool { + time.Sleep(500 * time.Millisecond) + return true + }) + t.Assert(r, true) + }() + time.Sleep(100 * time.Millisecond) + go func() { + defer wg.Done() + r := s.AddIfNotExistFuncLock("1", func() bool { + return true + }) + t.Assert(r, false) + }() + wg.Wait() + }) +} + func TestStrSet_Json(t *testing.T) { gtest.C(t, func(t *gtest.T) { s1 := []string{"a", "b", "d", "c"} @@ -343,46 +413,6 @@ func TestStrSet_Json(t *testing.T) { }) } -func TestStrSet_AddIfNotExistFunc(t *testing.T) { - gtest.C(t, func(t *gtest.T) { - s := gset.NewStrSet(true) - s.Add("1") - t.Assert(s.Contains("1"), true) - t.Assert(s.Contains("2"), false) - - s.AddIfNotExistFunc("2", func() string { - return "3" - }) - t.Assert(s.Contains("2"), false) - t.Assert(s.Contains("3"), true) - - s.AddIfNotExistFunc("3", func() string { - return "4" - }) - t.Assert(s.Contains("3"), true) - t.Assert(s.Contains("4"), false) - }) - - gtest.C(t, func(t *gtest.T) { - s := gset.NewStrSet(true) - s.Add("1") - t.Assert(s.Contains("1"), true) - t.Assert(s.Contains("2"), false) - - s.AddIfNotExistFuncLock("2", func() string { - return "3" - }) - t.Assert(s.Contains("2"), false) - t.Assert(s.Contains("3"), true) - - s.AddIfNotExistFuncLock("3", func() string { - return "4" - }) - t.Assert(s.Contains("3"), true) - t.Assert(s.Contains("4"), false) - }) -} - func TestStrSet_UnmarshalValue(t *testing.T) { type V struct { Name string diff --git a/internal/empty/empty.go b/internal/empty/empty.go index 675317138..52a4bf86f 100644 --- a/internal/empty/empty.go +++ b/internal/empty/empty.go @@ -12,8 +12,8 @@ import ( ) // IsEmpty checks whether given empty. -// It returns true if is in: 0, nil, false, "", len(slice/map/chan) == 0. -// Or else it returns true. +// It returns true if is in: 0, nil, false, "", len(slice/map/chan) == 0, +// or else it returns false. func IsEmpty(value interface{}) bool { if value == nil { return true @@ -49,6 +49,8 @@ func IsEmpty(value interface{}) bool { return value == "" case []byte: return len(value) == 0 + case []rune: + return len(value) == 0 default: // Finally using reflect. var rv reflect.Value diff --git a/net/ghttp/ghttp_server_admin_unix.go b/net/ghttp/ghttp_server_admin_unix.go index 748849193..7cca3a84e 100644 --- a/net/ghttp/ghttp_server_admin_unix.go +++ b/net/ghttp/ghttp_server_admin_unix.go @@ -9,6 +9,7 @@ package ghttp import ( + "github.com/gogf/gf/internal/intlog" "os" "os/signal" "syscall" @@ -26,14 +27,16 @@ func handleProcessSignal() { syscall.SIGQUIT, syscall.SIGKILL, syscall.SIGTERM, + syscall.SIGABRT, syscall.SIGUSR1, syscall.SIGUSR2, ) for { sig = <-procSignalChan + intlog.Printf(`signal received: %s`, sig.String()) switch sig { // 进程终止,停止所有子进程运行 - case syscall.SIGINT, syscall.SIGQUIT, syscall.SIGKILL, syscall.SIGTERM: + case syscall.SIGINT, syscall.SIGQUIT, syscall.SIGKILL, syscall.SIGTERM, syscall.SIGABRT: shutdownWebServers(sig.String()) return diff --git a/os/gfile/gfile.go b/os/gfile/gfile.go index 0c0f2dcbd..bc5de9e89 100644 --- a/os/gfile/gfile.go +++ b/os/gfile/gfile.go @@ -42,7 +42,7 @@ var ( func init() { // Initialize internal package variable: tempDir. - if !Exists(tempDir) { + if Separator == "/" && !Exists(tempDir) { tempDir = os.TempDir() } // Initialize internal package variable: selfPath. diff --git a/os/gfsnotify/gfsnotify_watcher.go b/os/gfsnotify/gfsnotify_watcher.go index b9fc4aa66..29228086d 100644 --- a/os/gfsnotify/gfsnotify_watcher.go +++ b/os/gfsnotify/gfsnotify_watcher.go @@ -26,11 +26,11 @@ func (w *Watcher) Add(path string, callbackFunc func(event *Event), recursive .. // // The optional parameter specifies whether monitoring the recursively, which is true in default. func (w *Watcher) AddOnce(name, path string, callbackFunc func(event *Event), recursive ...bool) (callback *Callback, err error) { - w.nameSet.AddIfNotExistFuncLock(name, func() string { + w.nameSet.AddIfNotExistFuncLock(name, func() bool { // Firstly add the path to watcher. callback, err = w.addWithCallbackFunc(name, path, callbackFunc, recursive...) if err != nil { - return "" + return false } // If it's recursive adding, it then adds all sub-folders to the monitor. // NOTE: @@ -49,7 +49,7 @@ func (w *Watcher) AddOnce(name, path string, callbackFunc func(event *Event), re } } } - return name + return true }) return } diff --git a/os/gproc/gproc_process.go b/os/gproc/gproc_process.go index fd9a99bd4..3bfd03aff 100644 --- a/os/gproc/gproc_process.go +++ b/os/gproc/gproc_process.go @@ -116,10 +116,12 @@ func (p *Process) Kill() error { p.Manager.processes.Remove(p.Pid()) } if runtime.GOOS != "windows" { - p.Process.Release() + if err = p.Process.Release(); err != nil { + return err + } } - p.Process.Wait() - return nil + _, err = p.Process.Wait() + return err } else { return err }