mirror of
https://github.com/golang/go
synced 2024-11-22 23:50:03 -07:00
syscall: fix data races in LazyDLL/LazyProc
Reincarnation of https://golang.org/cl/6817086 (sent from another account). It is ugly because sync.Once will cause allocation of a closure. Fixes #4343. R=golang-dev, bradfitz, alex.brainman CC=golang-dev https://golang.org/cl/6856046
This commit is contained in:
parent
8b7ea6489c
commit
9b4aaa418f
@ -6,6 +6,8 @@ package syscall
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DLLError describes reasons for DLL load failures.
|
// DLLError describes reasons for DLL load failures.
|
||||||
@ -166,7 +168,9 @@ type LazyDLL struct {
|
|||||||
// Load loads DLL file d.Name into memory. It returns an error if fails.
|
// Load loads DLL file d.Name into memory. It returns an error if fails.
|
||||||
// Load will not try to load DLL, if it is already loaded into memory.
|
// Load will not try to load DLL, if it is already loaded into memory.
|
||||||
func (d *LazyDLL) Load() error {
|
func (d *LazyDLL) Load() error {
|
||||||
if d.dll == nil {
|
// Non-racy version of:
|
||||||
|
// if d.dll == nil {
|
||||||
|
if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&d.dll))) == nil {
|
||||||
d.mu.Lock()
|
d.mu.Lock()
|
||||||
defer d.mu.Unlock()
|
defer d.mu.Unlock()
|
||||||
if d.dll == nil {
|
if d.dll == nil {
|
||||||
@ -174,7 +178,9 @@ func (d *LazyDLL) Load() error {
|
|||||||
if e != nil {
|
if e != nil {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
d.dll = dll
|
// Non-racy version of:
|
||||||
|
// d.dll = dll
|
||||||
|
atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&d.dll)), unsafe.Pointer(dll))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -217,7 +223,9 @@ type LazyProc struct {
|
|||||||
// an error if search fails. Find will not search procedure,
|
// an error if search fails. Find will not search procedure,
|
||||||
// if it is already found and loaded into memory.
|
// if it is already found and loaded into memory.
|
||||||
func (p *LazyProc) Find() error {
|
func (p *LazyProc) Find() error {
|
||||||
if p.proc == nil {
|
// Non-racy version of:
|
||||||
|
// if p.proc == nil {
|
||||||
|
if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&p.proc))) == nil {
|
||||||
p.mu.Lock()
|
p.mu.Lock()
|
||||||
defer p.mu.Unlock()
|
defer p.mu.Unlock()
|
||||||
if p.proc == nil {
|
if p.proc == nil {
|
||||||
@ -229,7 +237,9 @@ func (p *LazyProc) Find() error {
|
|||||||
if e != nil {
|
if e != nil {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
p.proc = proc
|
// Non-racy version of:
|
||||||
|
// p.proc = proc
|
||||||
|
atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&p.proc)), unsafe.Pointer(proc))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
Loading…
Reference in New Issue
Block a user