Skip to content

Commit b1efb0e

Browse files
committed
feat: no panic on same goroutine
1 parent 162407d commit b1efb0e

File tree

2 files changed

+46
-12
lines changed

2 files changed

+46
-12
lines changed

item.go

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ type Item[T any] struct {
1818
cfg any
1919
// align 64
2020

21+
// id only take effect on issync = True
22+
id int64
23+
// align 64
24+
2125
val T
2226
}
2327

@@ -36,7 +40,9 @@ func (b *Item[T]) Trans() T {
3640
panic("use after destroy")
3741
}
3842
if b.pool.issync {
39-
b.stat.setinsyncop(true)
43+
if !b.stat.setinsyncop(true) {
44+
panic("non-unique op")
45+
}
4046
}
4147
val := b.val
4248
atomic.StoreUintptr(
@@ -51,7 +57,10 @@ func (b *Item[T]) Trans() T {
5157
// and will be Reset on putting back.
5258
func (b *Item[T]) HasInvolved() bool {
5359
if b.pool.issync {
54-
b.stat.setinsyncop(true)
60+
if !b.stat.setinsyncop(true) && getGoroutineID() != b.id {
61+
panic("non-unique op")
62+
}
63+
atomic.StoreInt64(&b.id, getGoroutineID())
5564
defer b.stat.setinsyncop(false)
5665
}
5766
return b.stat.isbuffered()
@@ -65,7 +74,10 @@ func (b *Item[T]) V(f func(T)) {
6574
panic("use after destroy")
6675
}
6776
if b.pool.issync {
68-
b.stat.setinsyncop(true)
77+
if !b.stat.setinsyncop(true) && getGoroutineID() != b.id {
78+
panic("non-unique op")
79+
}
80+
atomic.StoreInt64(&b.id, getGoroutineID())
6981
defer b.stat.setinsyncop(false)
7082
}
7183
f(b.val)
@@ -80,7 +92,10 @@ func (b *Item[T]) P(f func(*T)) {
8092
panic("use after destroy")
8193
}
8294
if b.pool.issync {
83-
b.stat.setinsyncop(true)
95+
if !b.stat.setinsyncop(true) && getGoroutineID() != b.id {
96+
panic("non-unique op")
97+
}
98+
atomic.StoreInt64(&b.id, getGoroutineID())
8499
defer b.stat.setinsyncop(false)
85100
}
86101
f(&b.val)
@@ -93,7 +108,10 @@ func (b *Item[T]) Copy() (cb *Item[T]) {
93108
panic("use after destroy")
94109
}
95110
if b.pool.issync {
96-
b.stat.setinsyncop(true)
111+
if !b.stat.setinsyncop(true) && getGoroutineID() != b.id {
112+
panic("non-unique op")
113+
}
114+
atomic.StoreInt64(&b.id, getGoroutineID())
97115
defer b.stat.setinsyncop(false)
98116
}
99117
cb = b.pool.New(b.cfg)

status.go

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
package orbyte
22

3-
import "sync/atomic"
3+
import (
4+
"runtime"
5+
"strconv"
6+
"strings"
7+
"sync/atomic"
8+
)
49

510
const (
611
statusisbuffered = 1 << iota
@@ -16,6 +21,16 @@ func init() {
1621
destroyedstatus.setdestroyed(true)
1722
}
1823

24+
func getGoroutineID() int64 {
25+
var buf [64]byte
26+
n := runtime.Stack(buf[:], false)
27+
idField := strings.Fields(string(buf[:n]))[1]
28+
id, err := strconv.ParseInt(idField, 10, 64)
29+
if err != nil {
30+
panic(err)
31+
}
32+
return id
33+
}
1934
func (c status) mask(v bool, typ uintptr) (news status) {
2035
news = c
2136
if v {
@@ -39,22 +54,23 @@ func (c *status) setbool(v bool, typ uintptr) {
3954
}
4055
}
4156

42-
// setboolunique panic on non-unique set
43-
func (c *status) setboolunique(v bool, typ uintptr) {
57+
// setboolunique return false on non-unique set
58+
func (c *status) setboolunique(v bool, typ uintptr) bool {
4459
olds := atomic.LoadUintptr((*uintptr)(c))
4560
oldv := olds&typ != 0
4661
if oldv == v {
47-
panic("non-unique operation")
62+
return false
4863
}
4964
news := status(olds).mask(v, typ)
5065
for !atomic.CompareAndSwapUintptr((*uintptr)(c), olds, uintptr(news)) {
5166
olds = atomic.LoadUintptr((*uintptr)(c))
5267
oldv = olds&typ != 0
5368
if oldv == v {
54-
panic("non-unique operation")
69+
return false
5570
}
5671
news = status(olds).mask(v, typ)
5772
}
73+
return true
5874
}
5975

6076
func (c *status) loadbool(typ uintptr) bool {
@@ -77,6 +93,6 @@ func (c *status) setdestroyed(v bool) {
7793
c.setbool(v, statusdestroyed)
7894
}
7995

80-
func (c *status) setinsyncop(v bool) {
81-
c.setboolunique(v, statusinsyncop)
96+
func (c *status) setinsyncop(v bool) bool {
97+
return c.setboolunique(v, statusinsyncop)
8298
}

0 commit comments

Comments
 (0)