mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-09-22 01:48:11 +00:00
proc: Windows 共享内存 + 事件通知适配(Part 6.2 内核侧)
补齐内核侧的 Windows 创建端,与 6.1 的插件侧打开端配对。三平台 (linux/darwin/windows)现在都能构建 internal/plugin/proc。 ## Windows 走命名内核对象(无 fd 继承语义) os/exec 的 ExtraFiles 在 Windows 实现里不被支持,故: - shmalloc_windows.go:CreateFileMappingW(INVALID_HANDLE_VALUE + 命名 → 系统页文件支撑的匿名段,不落盘)+ MapViewOfFile - evtfd_windows.go:CreateEventW 命名 Event 对象 + SetEvent 通知 - shmpass_windows.go:把段名/对象名经环境变量注入子进程 (HOMEAGENT_SHM_STAGE / HOMEAGENT_SHM_EVTRING / HOMEAGENT_EVT_EVENT) 名字带 PID + 递增序号:多个 homed 实例并存时不能撞名。 Event 与 eventfd 的语义差异:Event 是二元信号,多次 SetEvent 只对应一次 唤醒,不累积。不影响正确性——消费者被唤醒后按 readSeq 追 writeSeq 批量 drain,丢的是"唤醒次数"不是"事件";事件环本身就允许溢出丢弃并让消费者 知道丢了(dropped 计数),通知面从来不是可靠投递语义。 ## 传递机制抽象为 shmpass_*.go Plugin.Start 不再直接构造 ExtraFiles 列表,改为问 Host 要: Env: p.host.procEnvForShm() // Windows 返回段名,Unix 返回 nil ExtraFiles: p.host.procExtraFilesForShm() // Unix 返回 fd 列表,Windows 返回 nil 平台差异被收敛到这一对函数,Plugin/coreHandler/stage 全部平台无关。 ## macOS pipe 生命周期修正 原实现只返回读端 fd,写端 *os.File 无人持有 → 可能被 GC 回收 → 读端收到 EOF 而非阻塞 → 消费循环变忙转。改为 pipePair 表同时持有两端, evtfdClose 一并关闭。 ## E2E 测试跟进模板拆分 模板从单文件拆成三个(主体 + unix/windows 挂载),测试需要一并落盘, 否则编译报 attachStageShm undefined。procRuntimeTemplates 表必须与 SDK 仓 proc_runtime.go 的 procRuntimeFiles 一致。 验证:三平台 go build ./internal/plugin/... 通过(gojieba 的 cgo 依赖 导致 internal/memory 在非 linux 失败,与本次无关); go test -race ./internal/plugin/... 全绿,含 2 项真实模板 E2E。 Ref: docs/zh/架构迁移评估.md §9.2、docs/zh/plugin-migration-plan.md Part 6
This commit is contained in:
@ -62,6 +62,8 @@ type Process struct {
|
||||
|
||||
// shmSize 是握手时告知插件的共享段大小(0 表示本插件不用共享段)。
|
||||
shmSize int
|
||||
// evtRingSize 是事件环段大小(0 表示不支持事件环)。
|
||||
evtRingSize int
|
||||
}
|
||||
|
||||
// RequestHandler 处理插件 → 内核的调用。
|
||||
@ -79,6 +81,8 @@ type Options struct {
|
||||
ExtraFiles []*os.File
|
||||
// ShmSize 是共享段大小,握手时告知插件(与 ExtraFiles[0] 的 memfd 对应)。
|
||||
ShmSize int
|
||||
// EvtRingSize 是事件环段大小(0 表示不支持事件环)。
|
||||
EvtRingSize int
|
||||
// Handler 处理插件反向调用。
|
||||
Handler RequestHandler
|
||||
// OnExit 进程退出回调。
|
||||
@ -127,18 +131,19 @@ func Spawn(name, bin string, opts Options) (*Process, error) {
|
||||
}
|
||||
|
||||
p := &Process{
|
||||
name: name,
|
||||
bin: bin,
|
||||
dir: opts.Dir,
|
||||
cmd: cmd,
|
||||
stdin: bufio.NewWriter(stdinPipe),
|
||||
stdout: stdoutPipe,
|
||||
pending: make(map[uint64]chan *Response),
|
||||
handler: opts.Handler,
|
||||
exited: make(chan struct{}),
|
||||
ready: make(chan struct{}),
|
||||
onExit: opts.OnExit,
|
||||
shmSize: opts.ShmSize,
|
||||
name: name,
|
||||
bin: bin,
|
||||
dir: opts.Dir,
|
||||
cmd: cmd,
|
||||
stdin: bufio.NewWriter(stdinPipe),
|
||||
stdout: stdoutPipe,
|
||||
pending: make(map[uint64]chan *Response),
|
||||
handler: opts.Handler,
|
||||
exited: make(chan struct{}),
|
||||
ready: make(chan struct{}),
|
||||
onExit: opts.OnExit,
|
||||
shmSize: opts.ShmSize,
|
||||
evtRingSize: opts.EvtRingSize,
|
||||
}
|
||||
|
||||
if err := cmd.Start(); err != nil {
|
||||
@ -190,6 +195,7 @@ func (p *Process) handshake(timeout time.Duration) error {
|
||||
PluginName: p.name,
|
||||
ShmVersion: shmVersion,
|
||||
ShmSize: p.shmSize,
|
||||
EvtRingSize: p.evtRingSize,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("proc: %s 握手失败: %w", p.name, err)
|
||||
|
||||
Reference in New Issue
Block a user