mirror of
https://github.com/fluffle/goirc
synced 2025-07-06 21:39:21 +00:00
change implementation of handler dispatching
This implementation has lockless handler lists, which reduces the time during which the handler map lock must be held. It doesn't unlink empty lists from the map, but as long as the set of events to handle is fixed and finite it's arguably better that way.
This commit is contained in:
parent
329a62d7d9
commit
b294365fc1
2 changed files with 134 additions and 73 deletions
38
client/dispatch_unsafe.go
Normal file
38
client/dispatch_unsafe.go
Normal file
|
@ -0,0 +1,38 @@
|
|||
package client
|
||||
|
||||
import (
|
||||
"sync/atomic"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type hNodePtr struct {
|
||||
ptr unsafe.Pointer
|
||||
}
|
||||
|
||||
func (p *hNodePtr) load() *hNode {
|
||||
return (*hNode)(atomic.LoadPointer(&p.ptr))
|
||||
}
|
||||
func (p *hNodePtr) store(new *hNode) {
|
||||
atomic.StorePointer(&p.ptr, unsafe.Pointer(new))
|
||||
}
|
||||
func (p *hNodePtr) swap(new *hNode) (old *hNode) {
|
||||
return (*hNode)(atomic.SwapPointer(&p.ptr, unsafe.Pointer(new)))
|
||||
}
|
||||
func (p *hNodePtr) compareAndSwap(old, new *hNode) (swapped bool) {
|
||||
return atomic.CompareAndSwapPointer(&p.ptr, unsafe.Pointer(old), unsafe.Pointer(new))
|
||||
}
|
||||
|
||||
type hNodeState uintptr
|
||||
|
||||
func (s *hNodeState) load() hNodeState {
|
||||
return hNodeState(atomic.LoadUintptr((*uintptr)(s)))
|
||||
}
|
||||
func (s *hNodeState) store(new hNodeState) {
|
||||
atomic.StoreUintptr((*uintptr)(s), uintptr(new))
|
||||
}
|
||||
func (s *hNodeState) swap(new hNodeState) (old hNodeState) {
|
||||
return hNodeState(atomic.SwapUintptr((*uintptr)(s), uintptr(new)))
|
||||
}
|
||||
func (s *hNodeState) compareAndSwap(old, new hNodeState) (swapped bool) {
|
||||
return atomic.CompareAndSwapUintptr((*uintptr)(s), uintptr(old), uintptr(new))
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue