// service.c — the same dispatch pattern in every service
static handler_fn handlers[] = {
[IPC_SERVICE_FUNCTION_CREATE] = handler_create,
[IPC_SERVICE_FUNCTION_DESTROY] = handler_destroy,
// ...
};
IPC_ENDPOINT void service_entry(
uint64_t cref, uint64_t method,
uint64_t a1, uint64_t a2, uint64_t a3) {
if (method < HANDLERS_COUNT && handlers[method])
OSIpcEndPointPoolReply(handlers[method](a1, a2, a3));
else
OSIpcEndPointPoolReply(0);
}
// statemgr_ipc.idl
service statemgr_ipc {
id = 0x9;
struct query { version = 1; char key[64]; };
struct result { version = 1; uint32_t found; };
uint64_t get(in query *request,
out result *response) id = 0x1;
};
Struct pointers use server-owned fixed receive buffers. The first call establishes SHM authorization per caller, method and parameter slot; later calls reuse the connection-level CRef and mapped address. A per-method lock covers copying, IPC and copy-back. Transport structs must declare a version; the generator adds abi_size / abi_version fields validated by the server. Variable-length data passes an explicit SHM handle and length.