mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-07 10:03:23 +09:00
The cross-process session is up. A server process is started on its own with an
endpoint and nothing else, it listens; a client started separately connects to
that name; Hello crosses, Welcome comes back with four SegmentRefs, six
descriptors cross by SCM_RIGHTS, and the client maps memory another process
created. ClientSession::Active() is non-null at the end of it, which is the flag
that arms the thirty-seven wire emitters.
INDEPENDENT, NOT FORKED - and that is a correction to this package's first
shape. The version committed an hour ago forked the server and handed it fds
3..6. It worked, and it was less code, but inheritance can only ever produce a
server that is a CHILD OF ITS CLIENT, which is the one arrangement the end state
cannot use: there the server is a standing application and the client is
somewhere else entirely, possibly on another kernel. CONTRACT-P6 §3.1 called
this Dial == Connect and filed it as a later shape. It is the primary one, and
fork/execve survives only as a way to START a process - every descriptor it used
to carry is gone.
What that costs and buys, concretely: the rendezvous becomes a NAME, so
SocketTransport grows Listen/AcceptPair/ConnectTo, with a bounded connect retry
that is the CLIENT's (a launcher that waited for the server to be ready would be
coupling the two again by the back door). The bells stop being inherited fds and
are created by the server and handed over with the segments - slots 4 and 5 of
six SCM_RIGHTS offers. And the client connects TWICE to the same path: an fd
offer is a sendmsg whose ancillary data rides with specific bytes, so it may not
share a socket with the framed control stream, or the frame reassembler and the
descriptor receiver race for the same bytes.
The pieces behind it:
- SessionSegments::AdoptFromDescriptors, which is the same Adopt+Map loop
AttachInProcess has run on every inproc session since P5. That was the point
of writing the inproc attach as dup+Adopt+Map rather than as an alias: only
the origin of the descriptor is new.
- ServerSession::SetExternalDoorbells, the narrow fix for a6 row A7-1 - the
§3.9 accessors abort for every role but InProcess, so a spawn apply thread
died before popping its first record. lk deletes them; until then an injected
pair is honest about where the bells come from.
- MG_Backend::InitServerRoleForSpawn: steps 1 and 2 of the split bring-up
extracted so the server process runs the SAME code the inproc server role
runs. The capability bits are a statement about the server's own backend and
a second copy would diverge the first time a backend registers a slot.
- ClientSession::FinishStartup: everything below the attach - producer, reply
pool, event ring, segment table, encoder, first CapsSnapshot, emitter tables -
shared verbatim between inproc and spawn. Its one parameter is not a
transport question: under inproc the client starts the apply thread because
there is no server-side main; under spawn there is one, and it started the
thread before it sent the first descriptor.
G1 CAUGHT A REAL LEAK on the way: InitServerRoleForSpawn was guarded on the
inside, so the pull build still DEFINED the symbol - 2 added, 1 removed, .text
+16 bytes. The whole function and its declaration are now inside the guard.
"It returns false there" is not the same as "it is not there", and the gate is
what said so.
Gates: ServerSpawnTest 4/4; unit suite 2344 with the same two pre-existing
environmental failures; G1 pull 0 added / 0 removed, .text 10822147 unchanged.
46 lines
2.0 KiB
C++
46 lines
2.0 KiB
C++
// MobileGL - MobileGL/MG_Backend/ServerRole.h
|
|
// Copyright (c) 2025-2026 MobileGL-Dev
|
|
// Licensed under the GNU Lesser General Public License v3.0:
|
|
// https://www.gnu.org/licenses/gpl-3.0.txt
|
|
// https://www.gnu.org/licenses/lgpl-3.0.txt
|
|
// SPDX-License-Identifier: LGPL-3.0-only
|
|
// End of Source File Header
|
|
|
|
// The server role's bring-up, as one entry point two shapes share.
|
|
//
|
|
// Steps 1 and 2 of Init.cpp's split bring-up - the server's private
|
|
// BackendObject, and the two CallMask halves computed from THAT backend's own
|
|
// function table. Under `inproc` InitSplitRoles calls it and then starts the
|
|
// client in the same process; under `spawn` the child's ServerMain calls it and
|
|
// then accepts a connection instead.
|
|
//
|
|
// ONE ENTRY POINT, not two, because the capability bits are a statement about
|
|
// the server's backend and only the server can compute them. A second copy in
|
|
// ServerMain would be a second answer to "does this backend own the XFB
|
|
// capture", diverging silently the first time a backend registers a slot.
|
|
|
|
#pragma once
|
|
|
|
#include <Includes.h>
|
|
|
|
// DECLARED ONLY IN A DISAGGREGATED BUILD. G1 requires the pull build's symbol
|
|
// set and .text to be byte-identical, and a definition guarded only on the
|
|
// inside still emits a symbol - measured, not assumed.
|
|
#if MOBILEGL_BUILD_DISAGGREGATED
|
|
|
|
namespace MobileGL::MG_Backend {
|
|
|
|
// Creates the server's BackendObject and publishes the consumed-subsystem
|
|
// mask and the capability bits onto ServerSessionInstance(). Does NOT create
|
|
// an EGL context: that happens later, on the apply thread, when the client's
|
|
// first eglMakeCurrent crosses as a blocking control request.
|
|
//
|
|
// Returns false when the backend could not be created, and the caller must
|
|
// then REFUSE TO CONTINUE rather than fall back - a server process that came
|
|
// up without a backend would accept a session it can never apply.
|
|
Bool InitServerRoleForSpawn();
|
|
|
|
} // namespace MobileGL::MG_Backend
|
|
|
|
#endif // MOBILEGL_BUILD_DISAGGREGATED
|