mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-07 18:13:23 +09:00
10 KiB
10 KiB
P11:persistent map 采纳档位诚实化(A 包主机半)
2026-09-29。依据 PLAN-P11.md §2 的 A1、A2 与 C 的文档修正。档位名按 design/07:T0 = client 分配 AHardwareBuffer、server 导入;T1 = server 导出 opaque fd;T2 = 拒绝,client 保留 shadow 并推送。本文只记实现所需的行为与门;A3 / A4(设备)与 B(T0)不在本文。
范围
档位在握手时定下(§1);断言 arena 落在哪一档、三臂登记(§2);文档漂移(§3)。
1. 档位由知道数据面的一侧在握手时定下(A1)
线上格式
- 无变化。LinkTerms、
RefuseCode、控制协议修订号(3)都不动:每一侧只判自己的旋钮,不需要把档位带过线。
规则(Transport/AdoptTier.cpp SettleAdoptTierAtHandshake)
| 数据面 | 侧 | MOBILEGL_IPC_ADOPT_TIER=0/1 |
|---|---|---|
| Stream(tcp) | client / server | 一行 W Refuse{AdoptTierOnStream, "T<n>"},本会话 T2;从不 Fatal |
| SharedSegments(inproc、fork / unix spawn) | client | Fatal{UnimplementedAdoptTier, "T<n>"},握手期、任何记录之前 |
| SharedSegments | server | 一行 W(档位由 client 定),T2 |
- 调用点:client
StartOverTransportPair(Welcome 校验后)与StartOverSocket(link terms 定下stream后、开数据连接前);serverServerSession::Accept(后端检查后、Welcome 前)。 - 使用处
Client::AdoptTierIsEmulate(PipeApply.cpp、PipeWireCodec.cpp仍问它):旋钮 2 → true;本进程已有握手定档 → true,不再打印;没有握手定过档的调用者 → 仍Fatal{UnimplementedAdoptTier}("no handshake settled")。旋钮 > 2(解析器不收)→ Fatal。 ServerSpawn从它拉起的子进程环境剔除MOBILEGL_IPC_*(五个 server 自有旋钮除外),所以 fork / unix spawn 的 server 看不到 client 的旋钮;tcp 的 server 读自己的环境。
普查
新的死亡走 SessionFail:abort 站点仍 79,family 词仍 45(复用 UnimplementedAdoptTier);refusal 词 3 → 4,AdoptTierOnStream 进 fatal_census.py 的 LOCAL_REFUSAL_WORDS(本地拒绝,不成为 Refuse 帧)。
门
- 单元:
AdoptTierStream.*(真 tcp 会话:client 0/1 → 会话起、一行拒绝、map_persistent得 DECLINED、之后仍 apply;进程内显示 server 0 → 每会话一行、不死);RemoteClientControls.AdoptTier{Zero,One}OverSharedSegmentsDiesAtTheHandshakeBeforeAnyMapPersistent(inproc 真握手,子进程在Start返回前死、具名);SplitBufferSet.OnlyAdoptTierTwoIsImplemented(函数级矩阵);PipeWireCodecTest.AdoptTier{Zero,One}AfterAStreamHandshakeIsADeclineOnTheWirePath与AnUnsettledAdoptTierStillDiesByNameOnTheWirePath。 - 集成:
{DirectGLES,DirectVulkan}.Tcp.AdoptTier0.LargeArenaAdoptionScenario.*(MOBILEGL_IPC_ADOPT_TIER=0;integration-tcp/integration-magma-tcp),AStreamSessionRefusesTheAdoptTierOnceByName读 client 日志恰一行,其余用例绿。tcp 专属:共享段上同一旋钮在握手期死(spawn_lane_parity.py的MAGMA_TCP_ONLY)。 - red-once:删 Stream 分支 → 两后端 tcp 条目 client 握手期
Fatal{UnimplementedAdoptTier}、无拒绝行,单元AdoptTierStream两例、codec 两例、SplitBufferSet一例红;把检查挪回使用处 → inproc 会话起来、map_persistent发出后才在 apply 线程死(子进程写出S),spawn 臂则静默跑 T2(server 环境被剔除)。
2. arena 落在哪一档(A2)
LargeArenaAdoptionScenario.TheArenaLandsInTheTierItsLaneDeclares:PersistentMapPeek读 arena 的IsBackendPersistentMapped,与车道的MGITEST_PERSISTENT_MAP_ARM比;问两次(NULL 定义后;一帧绘制 + SSBO 绑定 + dispatch 后)。未声明的车道跳过。- 声明:monolith = adopted(
DirectGLES.ResourceSubsystemOn/Off.、新DirectVulkan.ArenaArm.,都钉 monolith);split = emulated(Espryt 三臂经SplitLogPaths按条目声明;MagmaArena.块与 Buffers 车道)。 - 登记:
mgl_itest_register_split_arms("LargeArenaAdoptionScenario.*")(Espryt 进门、Magma 进信息层);Magma 进门:DirectVulkan.<arm>.Arena.(band 口味,六例)与 Buffers 车道(加六例,test.yml的 require-green 名单同步)。 - red-once:monolith 车道加
MOBILEGL_DISABLE_LARGE_BUFFER_ADOPTION=1→ 三条红;split 车道改声明 adopted → 两后端 8 条红。删PipeApply.cpp的 R-6 拒绝不会让 Espryt inproc 采纳(实测仍 emulated):split 下 client 的采纳门经线路走,codec 不调 applier 就答 DECLINED;applier 只在 server 角色自己发射时被问到(只有 Magma 的EnsureGpuResidentStorage),而 Magma 的线路表MapPersistent恒返回空。
3. 文档漂移(C)
Config.h:大 buffer 采纳下的 SubData 自0ee3384b起经 resident-subdata GPU 有序落地,不是"plain memcpy"。MG_Backend/Init.cpp:DirectVulkan 在非 monolith 下注册线路资源表(VkBufferManager::RegisterWireResourceOps)并声明 bit 7。- 档位命名按
design/07:PersistentMapTracker.h注释已改。protocol.fbs的Adopt = 6 // server-owned adopted store注释没改:protocol_revision_pin.py对整文件取 sha256,改注释要 bump 修订号。 CONTRACT-P6.md、design/06、design/07的"stream 上具名拒绝"现为真,已指向本节代码。
不变量
- G1:新代码全在
MOBILEGL_BUILD_DISAGGREGATED下(MG_Remote)。 - 线上格式与控制协议修订号不变(3)。(A 包;PAIR 包把修订号升到 4,见下节。)
PAIR:socket client 的两条连接按身份配对(B0 F2)
依据 B0-CROSS-APP.md F2:server 按到达顺序配对(AcceptPair,"先到是控制、后到是 aux"),设备上 server app 的就绪探测(一次空 connect() + close())成了下一个真 client 的控制连接,会话读到探测的套接字后退出(control peer closed before sending a first frame),client no Welcome … (rc=6);两个 client 同时连也会互换半边。
线上格式
protocol.fbs追加table PairBind { nonce: [ubyte]; aux: bool; }与CtrlMsg末尾的PairBind。控制协议修订号 3 → 4(mg_protocol_base.h,protocol_revision_pins.json已钉),wireFingerprint随之变。SocketTransport::ConnectTo(unix:与 fork spawn 两条 client 路径都走它;tcp://上只有测试用):CSPRNG 取 16 字节 nonce,控制、aux 两条连接各以一帧PairBind{nonce, aux}开头;控制连接上 Hello 在它之后。编解码在Transport/PairBind.h。- TCP 产品路径不变:
ConnectControl单连接,数据连接凭 server 发的Welcome.dataNonce绑定(DataBind,PH-7 (4)),TcpSupervisor的预认证门本来就丢探测。
规则(Server/PairAcceptor.{h,cpp},取代已删的 SocketTransport::AcceptPair)
| 连接的首帧 / 状态 | 处置 |
|---|---|
| 一字节未发就关(就绪探测) | 关闭,D 级日志 |
PairBind,另一角色同 nonce 已在等 |
成对交出(控制作流、aux 作描述符通道) |
PairBind,同 nonce 同角色已在等 |
Refuse{Authentication},关新来者 |
Hello(修订号 < 4 的 client) |
按 RunSession 的顺序问:token → 线上格式;旧 client 得 Refuse{WireFingerprint},都过的仍 Refuse{MalformedHello};从不配对 |
DataBind / 其它 |
Refuse{Authentication} "data connection names no live session" / Refuse{MalformedHello} + 形状细节 |
自 accept 起 2000 ms 内未发 PairBind,或伙伴未到 |
控制与未识别者 Refuse{Authentication} 后关;aux 直接关(其 client 在那里只收描述符);W 日志 |
| 同时未配对的超过 16 条 | 丢最老的未识别者(没有则最老者),Refuse{Busy} |
- 从不读过
PairBind一个字节(FirstFrameAssembler):控制连接后面的 Hello 归会话读,aux 后面是SCM_RIGHTS。 - 有状态:A-control、B-control、B-aux、A-aux 时先交出 B,A-control 留给下一次
Accept。Accept(timeoutMs)超时返回TIMEOUT,未配对的留着。 - 调用点:
UnixInProcessSupervisor(成员)与mobilegl_server_main的 unix 分支。--serve的会话子进程CloseInForkedChild(只close,不shutdown);单会话形状配对后即析构,其余等待者得Refuse{Busy}。RefuseBusy不变(Hello 仍在套接字里)。
版本互通
| 修订 3 server | 修订 4 server | |
|---|---|---|
| 修订 3 client | — | PairAcceptor 代答 Refuse{WireFingerprint},从不配对 |
| 修订 4 client | 旧 server 按顺序配对后首帧是 PairBind → Refuse{MalformedHello} "first control frame is not a verifiable Hello";旧会话退出若抢在 client 发 Hello 之前,client 只见发送失败 |
正常 |
门
- 单元
Endpoints/PairAcceptorTest.*/{unix,tcp}(8 例):(1) 探测后紧跟 client;(2) 四条交错;(3) 孤儿 aux 过预算被关、下一个 client 成对;(4) Hello 先到的旧 client 具名拒绝。每例用ServesExactly证身份(控制双向各一帧 + 该 client 的 aux 字节是 server aux 上的头几个字节)。 - 端到端
ServerSpawnTest.AStrayConnectionAheadOfTheClientDoesNotTakeItsSession:单会话 unix server,探测之后真 client 握手成功、server 退出 0。 - red-once:
PairAcceptor::Accept换回到达顺序配对(仍读掉首帧,只差配对规则)→ 单元 8/8 红((1) 控制连接是已关的探测;(2) aux 读到的不是本 client 的字节),端到端握手 rc=6(与设备上no Welcome … (rc=6)同);对照StartsAServerProcessAndHandshakesAcrossIt仍绿。拷回原文件、cmp字节相同后复绿。
不变量
- G1:新代码全在
MG_Remote(MOBILEGL_BUILD_DISAGGREGATED下)。 - 未改:
TcpSupervisor、预认证门、DataBind、会话读 Hello 的路径。