Skip to content

Commit 783d0a7

Browse files
committed
Make initializer optional
1 parent e4cb9f8 commit 783d0a7

File tree

4 files changed

+81
-34
lines changed

4 files changed

+81
-34
lines changed

plugin.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,31 @@ package dlplugin
1414

1515
// PluginInitializer provides an interface which is used to initialize a plugin interface.
1616
type PluginInitializer interface {
17-
// Init denotes a function type which initializes a plugin API.
17+
// Init initializes a plugin API.
1818
Init(lookup func(symName string) (uintptr, error)) error
1919
}
2020

2121
// Plugin is a loaded plugin.
2222
type Plugin struct {
2323
handler uintptr
2424
filepath string
25+
name string
2526
}
2627

2728
// Close closes a plugin.
2829
func (p *Plugin) Close() error {
2930
return libClose(p)
3031
}
3132

33+
// Init provides a lookup function and calls an initializer's Init method.
34+
func (p *Plugin) Init(initializer PluginInitializer) error {
35+
return libInit(p, initializer)
36+
}
37+
3238
// Open opens a plugin.
3339
// If a path has already been opened, then the existing *Plugin is returned.
3440
// It is safe for concurrent use by multiple goroutines.
41+
// If the initializer is nil the initialization process will be skipped.
3542
func Open(path string, initializer PluginInitializer) (*Plugin, error) {
3643
return libOpen(path, initializer)
3744
}

plugin_dl.go

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -87,25 +87,17 @@ func libOpen(name string, initializer PluginInitializer) (*Plugin, error) {
8787
plugins = make(map[string]*Plugin)
8888
}
8989

90-
p = &Plugin{handler: uintptr(h), filepath: filepath}
90+
p = &Plugin{handler: uintptr(h), filepath: filepath, name: name}
9191

92-
lookupFunc := func(symName string) (uintptr, error) {
93-
cname := make([]byte, len(symName)+1)
94-
copy(cname, symName)
92+
if initializer != nil {
93+
lookupFunc := produceLookup(h, name)
9594

96-
p := C.dlplugin_lookup(h, (*C.char)(unsafe.Pointer(&cname[0])), &cErr)
97-
if p == 0 {
98-
return 0, errors.New(`dlplugin.Open("` + name + `"): could not find symbol ` + symName + `: ` + C.GoString(cErr))
99-
}
95+
if err := initializer.Init(lookupFunc); err != nil {
96+
C.dlplugin_close(C.uintptr_t(p.handler))
97+
pluginsMu.Unlock()
10098

101-
return uintptr(p), nil
102-
}
103-
104-
if err := initializer.Init(lookupFunc); err != nil {
105-
C.dlplugin_close(C.uintptr_t(p.handler))
106-
pluginsMu.Unlock()
107-
108-
return nil, err
99+
return nil, err
100+
}
109101
}
110102

111103
plugins[filepath] = p
@@ -125,7 +117,33 @@ func libClose(p *Plugin) error {
125117
return nil
126118
}
127119

120+
func produceLookup(h C.uintptr_t, name string) func(symName string) (uintptr, error) {
121+
return func(symName string) (uintptr, error) {
122+
var cErr *C.char
123+
cname := make([]byte, len(symName)+1)
124+
copy(cname, symName)
125+
126+
p := C.dlplugin_lookup(h, (*C.char)(unsafe.Pointer(&cname[0])), &cErr)
127+
if p == 0 {
128+
return 0, errors.New(`dlplugin.Open("` + name + `"): could not find symbol ` + symName + `: ` + C.GoString(cErr))
129+
}
130+
131+
return uintptr(p), nil
132+
}
133+
}
134+
135+
func libInit(p *Plugin, initializer PluginInitializer) error {
136+
pluginsMu.RLock()
137+
138+
lookup := produceLookup(C.uintptr_t(p.handler), p.name)
139+
err := initializer.Init(lookup)
140+
141+
pluginsMu.RUnlock()
142+
143+
return err
144+
}
145+
128146
var (
129-
pluginsMu sync.Mutex
147+
pluginsMu sync.RWMutex
130148
plugins map[string]*Plugin
131149
)

plugin_stubs.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,7 @@ func libOpen(name string, initializer PluginInitializer) (*Plugin, error) {
1717
func libClose(p *Plugin) error {
1818
return errors.New("dlplugin: not implemented")
1919
}
20+
21+
func libInit(p *Plugin, initializer PluginInitializer) error {
22+
return errors.New("dlplugin: not implemented")
23+
}

plugin_win.go

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -94,23 +94,15 @@ func libOpen(name string, initializer PluginInitializer) (*Plugin, error) {
9494

9595
p = &Plugin{handler: uintptr(h), filepath: filepath}
9696

97-
lookupFunc := func(symName string) (uintptr, error) {
98-
cname := make([]byte, len(symName)+1)
99-
copy(cname, symName)
97+
if initializer != nil {
98+
lookupFunc := produceLookup(h, name)
10099

101-
p := C.dlplugin_lookup(h, (*C.char)(unsafe.Pointer(&cname[0])), &cErr)
102-
if p == 0 {
103-
return 0, errors.New(`dlplugin.Open("` + name + `"): could not find symbol ` + symName + `: ` + formatWinErr(cErr).Error())
104-
}
100+
if err := initializer.Init(lookupFunc); err != nil {
101+
C.dlplugin_close(C.uintptr_t(p.handler))
102+
pluginsMu.Unlock()
105103

106-
return uintptr(p), nil
107-
}
108-
109-
if err := initializer.Init(lookupFunc); err != nil {
110-
C.dlplugin_close(C.uintptr_t(p.handler))
111-
pluginsMu.Unlock()
112-
113-
return nil, err
104+
return nil, err
105+
}
114106
}
115107

116108
plugins[filepath] = p
@@ -134,7 +126,33 @@ func libClose(p *Plugin) error {
134126
return nil
135127
}
136128

129+
func produceLookup(h C.uintptr_t, name string) func(symName string) (uintptr, error) {
130+
return func(symName string) (uintptr, error) {
131+
var cErr *C.char
132+
cname := make([]byte, len(symName)+1)
133+
copy(cname, symName)
134+
135+
p := C.dlplugin_lookup(h, (*C.char)(unsafe.Pointer(&cname[0])), &cErr)
136+
if p == 0 {
137+
return 0, errors.New(`dlplugin.Open("` + name + `"): could not find symbol ` + symName + `: ` + formatWinErr(cErr).Error())
138+
}
139+
140+
return uintptr(p), nil
141+
}
142+
}
143+
144+
func libInit(p *Plugin, initializer PluginInitializer) error {
145+
pluginsMu.RLock()
146+
147+
lookup := produceLookup(C.uintptr_t(p.handler), p.name)
148+
err := initializer.Init(lookup)
149+
150+
pluginsMu.RUnlock()
151+
152+
return err
153+
}
154+
137155
var (
138-
pluginsMu sync.Mutex
156+
pluginsMu sync.RWMutex
139157
plugins map[string]*Plugin
140158
)

0 commit comments

Comments
 (0)