Skip to content

Commit

Permalink
Merge pull request #239 from projectdiscovery/introduce_lockable
Browse files Browse the repository at this point in the history
introduce generic lockable type
  • Loading branch information
Mzack9999 authored Aug 16, 2023
2 parents 4024619 + bbf83fe commit c1b8b57
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 0 deletions.
20 changes: 20 additions & 0 deletions generic/lockable.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package generic

import (
"sync"
)

type Lockable[K any] struct {
V K
sync.RWMutex
}

func (v *Lockable[K]) Do(f func(val K)) {
v.Lock()
defer v.Unlock()
f(v.V)
}

func WithLock[K any](val K) *Lockable[K] {
return &Lockable[K]{V: val}
}
55 changes: 55 additions & 0 deletions generic/lockable_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package generic

import (
"sync"
"testing"
)

func TestDo(t *testing.T) {
val := 10
l := WithLock(val)
l.Do(func(v int) {
if v != val {
t.Errorf("Expected %d, got %d", val, v)
}
})
}

func TestLockableConcurrency(t *testing.T) {
l := WithLock(0)

var wg sync.WaitGroup

for i := 0; i < 100; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for j := 0; j < 1000; j++ {
l.Do(func(v int) {
v++
l.V = v
})
}
}()
}

wg.Wait()

if l.V != 100*1000 {
t.Errorf("Expected counter to be %d, but got %d", 100*1000, l.V)
}
}

func TestLockableStringManipulation(t *testing.T) {
str := "initial"
l := WithLock(str)

l.Do(func(s string) {
s += " - updated"
l.V = s
})

if l.V != "initial - updated" {
t.Errorf("Expected 'initial - updated', got '%s'", str)
}
}

0 comments on commit c1b8b57

Please sign in to comment.