Skip to content

Commit 6622345

Browse files
dongwlinCopilot
andauthored
refactor: lifecycle (#39)
* fix: release partially loaded native libraries on init failure Co-authored-by: Copilot <copilot@github.com> * refactor: rename Init to Initialize and Release to Shutdown for clarity * refactor: make Init idempotent by removing ErrAlreadyInitialized * refactor: rename Init to Initialize in TestMain for consistency * refactor: make Release idempotent by removing ErrNotInitialized Co-authored-by: Copilot <copilot@github.com> * refactor: centralize native symbol registration and cleanup - move native symbol bindings into Entry tables - clear registered function vars after successful unload - update api-check for Entry-based registrations Co-authored-by: Copilot <copilot@github.com> * fix: change library name variables to constants Co-authored-by: Copilot <copilot@github.com> * docs: update CHANGELOG * docs: add concurrency safety notes to Init, IsInited, and Release functions Co-authored-by: Copilot <copilot@github.com> --------- Co-authored-by: Copilot <copilot@github.com>
1 parent 7a918a7 commit 6622345

11 files changed

Lines changed: 581 additions & 344 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,9 @@
113113
- `Init()` 不再隐式应用默认全局配置,仅在显式传入对应 `WithXxx` 时才会调用设置。
114114
- `defaultInitConfig()` 已移除,`Init()` 现在直接使用 `initConfig{}` 初始化。
115115
- `WithPluginPaths` 会对输入切片进行拷贝,避免外部后续修改影响已构建的选项。
116+
- `Init()``Release()` 现为幂等操作:重复初始化或在未初始化状态下释放都会直接返回 `nil`;原导出的 `ErrAlreadyInitialized``ErrNotInitialized` 已移除。
117+
- `Init()` 过程中若某个原生库加载失败,会自动释放此前已成功加载的库,避免残留半初始化状态。
118+
- `LibraryLoadError` 现在会稳定包含库名与尝试加载的完整路径,便于排查动态库装载问题。
116119

117120
#### Toolkit
118121

internal/buffer/main_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88
)
99

1010
func TestMain(m *testing.M) {
11-
native.Init("")
11+
native.Initialize("")
1212

1313
os.Exit(m.Run())
1414
}

internal/native/agent_client.go

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import (
1010

1111
var maaAgentClient uintptr
1212

13+
const maaAgentClientName = "MaaAgentClient"
14+
1315
var (
1416
MaaAgentClientCreateV2 func(identifier uintptr) uintptr
1517
MaaAgentClientCreateTcp func(port uint16) uintptr
@@ -28,14 +30,32 @@ var (
2830
MaaAgentClientGetCustomActionList func(client uintptr, buffer uintptr) bool
2931
)
3032

33+
var agentClientEntries = []Entry{
34+
{&MaaAgentClientCreateV2, "MaaAgentClientCreateV2"},
35+
{&MaaAgentClientCreateTcp, "MaaAgentClientCreateTcp"},
36+
{&MaaAgentClientDestroy, "MaaAgentClientDestroy"},
37+
{&MaaAgentClientIdentifier, "MaaAgentClientIdentifier"},
38+
{&MaaAgentClientBindResource, "MaaAgentClientBindResource"},
39+
{&MaaAgentClientRegisterResourceSink, "MaaAgentClientRegisterResourceSink"},
40+
{&MaaAgentClientRegisterControllerSink, "MaaAgentClientRegisterControllerSink"},
41+
{&MaaAgentClientRegisterTaskerSink, "MaaAgentClientRegisterTaskerSink"},
42+
{&MaaAgentClientConnect, "MaaAgentClientConnect"},
43+
{&MaaAgentClientDisconnect, "MaaAgentClientDisconnect"},
44+
{&MaaAgentClientConnected, "MaaAgentClientConnected"},
45+
{&MaaAgentClientAlive, "MaaAgentClientAlive"},
46+
{&MaaAgentClientSetTimeout, "MaaAgentClientSetTimeout"},
47+
{&MaaAgentClientGetCustomRecognitionList, "MaaAgentClientGetCustomRecognitionList"},
48+
{&MaaAgentClientGetCustomActionList, "MaaAgentClientGetCustomActionList"},
49+
}
50+
3151
func initAgentClient(libDir string) error {
3252
libName := getMaaAgentClientLibrary()
3353
libPath := filepath.Join(libDir, libName)
3454

3555
handle, err := openLibrary(libPath)
3656
if err != nil {
3757
return &LibraryLoadError{
38-
LibraryName: "MaaAgentClient",
58+
LibraryName: maaAgentClientName,
3959
LibraryPath: libPath,
4060
Err: err,
4161
}
@@ -62,23 +82,24 @@ func getMaaAgentClientLibrary() string {
6282
}
6383

6484
func registerAgentClient() {
65-
purego.RegisterLibFunc(&MaaAgentClientCreateV2, maaAgentClient, "MaaAgentClientCreateV2")
66-
purego.RegisterLibFunc(&MaaAgentClientCreateTcp, maaAgentClient, "MaaAgentClientCreateTcp")
67-
purego.RegisterLibFunc(&MaaAgentClientDestroy, maaAgentClient, "MaaAgentClientDestroy")
68-
purego.RegisterLibFunc(&MaaAgentClientIdentifier, maaAgentClient, "MaaAgentClientIdentifier")
69-
purego.RegisterLibFunc(&MaaAgentClientBindResource, maaAgentClient, "MaaAgentClientBindResource")
70-
purego.RegisterLibFunc(&MaaAgentClientRegisterResourceSink, maaAgentClient, "MaaAgentClientRegisterResourceSink")
71-
purego.RegisterLibFunc(&MaaAgentClientRegisterControllerSink, maaAgentClient, "MaaAgentClientRegisterControllerSink")
72-
purego.RegisterLibFunc(&MaaAgentClientRegisterTaskerSink, maaAgentClient, "MaaAgentClientRegisterTaskerSink")
73-
purego.RegisterLibFunc(&MaaAgentClientConnect, maaAgentClient, "MaaAgentClientConnect")
74-
purego.RegisterLibFunc(&MaaAgentClientDisconnect, maaAgentClient, "MaaAgentClientDisconnect")
75-
purego.RegisterLibFunc(&MaaAgentClientConnected, maaAgentClient, "MaaAgentClientConnected")
76-
purego.RegisterLibFunc(&MaaAgentClientAlive, maaAgentClient, "MaaAgentClientAlive")
77-
purego.RegisterLibFunc(&MaaAgentClientSetTimeout, maaAgentClient, "MaaAgentClientSetTimeout")
78-
purego.RegisterLibFunc(&MaaAgentClientGetCustomRecognitionList, maaAgentClient, "MaaAgentClientGetCustomRecognitionList")
79-
purego.RegisterLibFunc(&MaaAgentClientGetCustomActionList, maaAgentClient, "MaaAgentClientGetCustomActionList")
85+
for _, entry := range agentClientEntries {
86+
purego.RegisterLibFunc(entry.ptrToFunc, maaAgentClient, entry.name)
87+
}
88+
}
89+
90+
func releaseAgentClient() error {
91+
err := unloadLibrary(maaAgentClient)
92+
if err != nil {
93+
return err
94+
}
95+
96+
unregisterAgentClient()
97+
98+
return nil
8099
}
81100

82-
func unregisterAgentClient() error {
83-
return unloadLibrary(maaAgentClient)
101+
func unregisterAgentClient() {
102+
for _, entry := range agentClientEntries {
103+
clearFuncVar(entry.ptrToFunc)
104+
}
84105
}

internal/native/agent_server.go

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import (
1111

1212
var maaAgentServer uintptr
1313

14+
const maaAgentServerName = "MaaAgentServer"
15+
1416
var (
1517
MaaAgentServerRegisterCustomRecognition func(name string, recognition MaaCustomRecognitionCallback, transArg unsafe.Pointer) bool
1618
MaaAgentServerRegisterCustomAction func(name string, action MaaCustomActionCallback, transArg unsafe.Pointer) bool
@@ -24,14 +26,27 @@ var (
2426
MaaAgentServerDetach func()
2527
)
2628

29+
var agentServerEntries = []Entry{
30+
{&MaaAgentServerRegisterCustomRecognition, "MaaAgentServerRegisterCustomRecognition"},
31+
{&MaaAgentServerRegisterCustomAction, "MaaAgentServerRegisterCustomAction"},
32+
{&MaaAgentServerAddResourceSink, "MaaAgentServerAddResourceSink"},
33+
{&MaaAgentServerAddControllerSink, "MaaAgentServerAddControllerSink"},
34+
{&MaaAgentServerAddTaskerSink, "MaaAgentServerAddTaskerSink"},
35+
{&MaaAgentServerAddContextSink, "MaaAgentServerAddContextSink"},
36+
{&MaaAgentServerStartUp, "MaaAgentServerStartUp"},
37+
{&MaaAgentServerShutDown, "MaaAgentServerShutDown"},
38+
{&MaaAgentServerJoin, "MaaAgentServerJoin"},
39+
{&MaaAgentServerDetach, "MaaAgentServerDetach"},
40+
}
41+
2742
func initAgentServer(libDir string) error {
2843
libName := getMaaAgentServerLibrary()
2944
libPath := filepath.Join(libDir, libName)
3045

3146
handle, err := openLibrary(libPath)
3247
if err != nil {
3348
return &LibraryLoadError{
34-
LibraryName: "MaaAgentServer",
49+
LibraryName: maaAgentServerName,
3550
LibraryPath: libPath,
3651
Err: err,
3752
}
@@ -58,18 +73,24 @@ func getMaaAgentServerLibrary() string {
5873
}
5974

6075
func registerAgentServer() {
61-
purego.RegisterLibFunc(&MaaAgentServerRegisterCustomRecognition, maaAgentServer, "MaaAgentServerRegisterCustomRecognition")
62-
purego.RegisterLibFunc(&MaaAgentServerRegisterCustomAction, maaAgentServer, "MaaAgentServerRegisterCustomAction")
63-
purego.RegisterLibFunc(&MaaAgentServerAddResourceSink, maaAgentServer, "MaaAgentServerAddResourceSink")
64-
purego.RegisterLibFunc(&MaaAgentServerAddControllerSink, maaAgentServer, "MaaAgentServerAddControllerSink")
65-
purego.RegisterLibFunc(&MaaAgentServerAddTaskerSink, maaAgentServer, "MaaAgentServerAddTaskerSink")
66-
purego.RegisterLibFunc(&MaaAgentServerAddContextSink, maaAgentServer, "MaaAgentServerAddContextSink")
67-
purego.RegisterLibFunc(&MaaAgentServerStartUp, maaAgentServer, "MaaAgentServerStartUp")
68-
purego.RegisterLibFunc(&MaaAgentServerShutDown, maaAgentServer, "MaaAgentServerShutDown")
69-
purego.RegisterLibFunc(&MaaAgentServerJoin, maaAgentServer, "MaaAgentServerJoin")
70-
purego.RegisterLibFunc(&MaaAgentServerDetach, maaAgentServer, "MaaAgentServerDetach")
76+
for _, entry := range agentServerEntries {
77+
purego.RegisterLibFunc(entry.ptrToFunc, maaAgentServer, entry.name)
78+
}
79+
}
80+
81+
func releaseAgentServer() error {
82+
err := unloadLibrary(maaAgentServer)
83+
if err != nil {
84+
return err
85+
}
86+
87+
unregisterAgentServer()
88+
89+
return nil
7190
}
7291

73-
func unregisterAgentServer() error {
74-
return unloadLibrary(maaAgentServer)
92+
func unregisterAgentServer() {
93+
for _, entry := range agentServerEntries {
94+
clearFuncVar(entry.ptrToFunc)
95+
}
7596
}

0 commit comments

Comments
 (0)