Skip to content

Commit

Permalink
- more refactoring work
Browse files Browse the repository at this point in the history
  • Loading branch information
iulianpascalau committed Dec 22, 2021
1 parent 48ed296 commit 7a7b23c
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 18 deletions.
42 changes: 29 additions & 13 deletions core/atomic/flag.go
Original file line number Diff line number Diff line change
@@ -1,34 +1,50 @@
package atomic

import "sync/atomic"
import (
"sync"
)

// Flag is an atomic flag
type Flag struct {
value uint32
mut sync.RWMutex
value bool
}

// SetReturningPrevious sets flag and returns its previous value
func (flag *Flag) SetReturningPrevious() bool {
previousValue := atomic.SwapUint32(&flag.value, 1)
return previousValue == 1
flag.mut.Lock()
previousValue := flag.value
flag.value = true
flag.mut.Unlock()

return previousValue
}

// Reset resets the flag, putting it in off position
func (flag *Flag) Reset() {
atomic.StoreUint32(&flag.value, 0)
flag.mut.Lock()
flag.value = false
flag.mut.Unlock()
}

// IsSet checks whether flag is set
func (flag *Flag) IsSet() bool {
value := atomic.LoadUint32(&flag.value)
return value == 1
flag.mut.RLock()
defer flag.mut.RUnlock()

return flag.value
}

// Toggle toggles the flag
func (flag *Flag) Toggle(set bool) {
if set {
_ = flag.SetReturningPrevious()
} else {
flag.Reset()
}
func (flag *Flag) Toggle() {
flag.mut.Lock()
flag.value = !flag.value
flag.mut.Unlock()
}

// SetValue sets the new value in the flag
func (flag *Flag) SetValue(newValue bool) {
flag.mut.Lock()
flag.value = newValue
flag.mut.Unlock()
}
39 changes: 34 additions & 5 deletions core/atomic/flag_test.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package atomic

import (
"github.com/stretchr/testify/assert"
"sync"
"testing"

"github.com/stretchr/testify/require"
)

func TestFlag_Set(t *testing.T) {
t.Parallel()

var flag Flag
var wg sync.WaitGroup

Expand All @@ -30,6 +33,8 @@ func TestFlag_Set(t *testing.T) {
}

func TestFlag_Reset(t *testing.T) {
t.Parallel()

var flag Flag
var wg sync.WaitGroup

Expand All @@ -52,20 +57,22 @@ func TestFlag_Reset(t *testing.T) {
require.False(t, flag.IsSet())
}

func TestFlag_Toggle(t *testing.T) {
func TestFlag_SetValue(t *testing.T) {
t.Parallel()

var flag Flag
var wg sync.WaitGroup

// First, Toggle(true)
wg.Add(2)

go func() {
flag.Toggle(true)
flag.SetValue(true)
wg.Done()
}()

go func() {
flag.Toggle(true)
flag.SetValue(true)
wg.Done()
}()

Expand All @@ -76,15 +83,37 @@ func TestFlag_Toggle(t *testing.T) {
wg.Add(2)

go func() {
flag.Toggle(false)
flag.SetValue(false)
wg.Done()
}()

go func() {
flag.Toggle(false)
flag.SetValue(false)
wg.Done()
}()

wg.Wait()
require.False(t, flag.IsSet())
}

func TestFlag_Toggle(t *testing.T) {
t.Parallel()

f := Flag{}
f.SetValue(true)

numToggles := 51
wg := sync.WaitGroup{}
wg.Add(numToggles)
for i := 0; i < numToggles; i++ {
go func() {
f.Toggle()

wg.Done()
}()
}

wg.Wait()

assert.False(t, f.IsSet())
}

0 comments on commit 7a7b23c

Please sign in to comment.