diff options
author | Luke Shumaker <lukeshu@sbcglobal.net> | 2015-09-18 17:47:06 -0400 |
---|---|---|
committer | Luke Shumaker <lukeshu@sbcglobal.net> | 2015-09-18 17:47:06 -0400 |
commit | 927e5d327209901cca56de0bccacf6d2b33e055a (patch) | |
tree | b1b36ec89d1653d9b66a41c8b01b4296399dcc82 | |
parent | 5d29d4c39d1c082535410510be6c54e349e1e3a7 (diff) |
dl: Keep track of if a handle has been closed
-rw-r--r-- | dl/dlfcn.go | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/dl/dlfcn.go b/dl/dlfcn.go index 3ab5abb..db8bd63 100644 --- a/dl/dlfcn.go +++ b/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 } |