From 927e5d327209901cca56de0bccacf6d2b33e055a Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Fri, 18 Sep 2015 17:47:06 -0400 Subject: dl: Keep track of if a handle has been closed --- dl/dlfcn.go | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) 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 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 } -- cgit v1.1-4-g5e80