summaryrefslogtreecommitdiff
path: root/src/dl/dlfcn.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/dl/dlfcn.go')
-rw-r--r--src/dl/dlfcn.go24
1 files changed, 23 insertions, 1 deletions
diff --git a/src/dl/dlfcn.go b/src/dl/dlfcn.go
index 3ab5abb..db8bd63 100644
--- a/src/dl/dlfcn.go
+++ b/src/dl/dlfcn.go
@@ -24,6 +24,7 @@ package dl
import (
"errors"
+ "sync"
"unsafe"
)
@@ -32,6 +33,8 @@ import (
//#include <dlfcn.h>
import "C"
+var HandleClosedError = errors.New("Handle is already closed")
+
type Flag int
// POSIX specifies these four flags to Open().
@@ -54,6 +57,8 @@ const (
type Handle struct {
c unsafe.Pointer
+ o int
+ l sync.RWMutex
}
// Open a shared object file, returning a Handle to it, or an error.
@@ -73,7 +78,7 @@ func Open(name string, flags Flag) (Handle, error) {
if ptr == nil {
return Handle{}, dlerror()
}
- return Handle{ptr}, nil
+ return Handle{c: ptr, o: 1}, nil
}
// Look up a symbol, and return a pointer to it.
@@ -82,6 +87,13 @@ func Open(name string, flags Flag) (Handle, error) {
// dl cannot obtain unsafe.Pointers without importing the unsafe
// package explicitly.
func (h Handle) Sym(symbol string) (uintptr, error) {
+ h.l.RLock()
+ defer h.l.RUnlock()
+
+ if h.o == 0 {
+ return 0, HandleClosedError
+ }
+
symbolC := C.CString(symbol)
defer C.free(unsafe.Pointer(symbolC))
@@ -97,11 +109,21 @@ func (h Handle) Sym(symbol string) (uintptr, error) {
// count; if the reference count drops below 0, then the object is
// unloaded.
func (h Handle) Close() error {
+ h.l.Lock()
+ defer h.l.Unlock()
+
+ if h.o == 0 {
+ return HandleClosedError
+ }
+
dlerror()
r := C.dlclose(h.c)
if r != 0 {
return dlerror()
}
+ if h.o == 1 {
+ h.o = 0
+ }
return nil
}