26 个 API · 进程内直连(tcc_add_symbol 按地址解析)

XServer 层 API 参考

宿主单进程实现,脚本按地址直调。其余一切能力皆为 xrt 或扩展符号——本页之外请查 xrt 分组索引。

拓扑查询(7)

retained lease 纪律:xsServerFind 返回带引用的租约,必须配对 xsServerRelease;枚举回调的参数只在回调内借用,保存前必须 xsServerRetain。host 由其 server lease 共同保护。

xsServerFind 查询

按全局唯一名查找 server,返回 retained lease。

XS_ServerInfo* xsServerFind(const char* sName);
返回:NULL = 未找到所有权:retained,必须 Release
示例
XS_ServerInfo* pSrv = xsServerFind("demo");
if ( pSrv != NULL ) {
    /* 使用拓扑信息 ... */
    xsServerRelease(pSrv);
}

xsServerRetain / xsServerRelease 查询

延长 server lease / 归还引用。连接存续期、枚举回调外保存前都要 Retain。

XS_ServerInfo* xsServerRetain(XS_ServerInfo* pServer); void xsServerRelease(XS_ServerInfo* pServer);
配对:每个 Retain 一个 Release意义:防止换代期间拓扑被回收

xsHostFind 查询

在 server 内按名查找 host;结果由传入的 server lease 共同保护(不需要单独 release)。

XS_HostInfo* xsHostFind(XS_ServerInfo* pServer, const char* sName);
前提:pServer 是你持有的 lease返回:NULL = 未找到

xsEnumServers / xsEnumHosts 查询

枚举全部 server / 某 server 的全部 host。参数只在回调内借用。

void xsEnumServers(XS_ServerEnumProc procEach, void* pUserData); void xsEnumHosts(XS_ServerInfo* pServer, XS_HostEnumProc procEach, void* pUserData);
回调返回:false = 终止枚举借用:回调外保存需 Retain
示例
static bool PrintServer(XS_ServerInfo* pServer, void* pUserData)
{
    printf("server: %s (%s)\n", pServer->Name, pServer->Class);
    return true;   /* 继续枚举 */
}
xsEnumServers(PrintServer, NULL);

xsConfigRoot 查询

返回 xs.json 顶层 Custom(非预设字段的全部内容),供应用读取自定义旋钮。

xvalue* xsConfigRoot(void);
所有权:retained,需 xrtValueRelease内容:根级非预设字段

热重载(7)

reload 是期望状态协调任务,不是同步命令。终态机:ACCEPTED → PREPARING → SUCCEEDED / FAILED / SUPERSEDED / CANCELLED;同 server 新意图覆盖未执行的旧意图,pending 上限 64。

xsReloadHostSubmit 重载

提交一个 host 的重载意图(以所属 server 为发布单元)。

XS_ReloadId xsReloadHostSubmit(XS_HostInfo* pHost);
返回:0 = 未受理;非零 = 稳定 ID语义:异步,查询用 xsReloadQuery

xsReloadServerSubmit 重载

按名称提交整个 server 的重载意图。

XS_ReloadId xsReloadServerSubmit(const char* sName);
返回:0 = 未受理

xsReloadAllSubmit 重载

整批事务:全部 server 的候选预编译,任何失败整体回滚。

XS_ReloadId xsReloadAllSubmit(void);
事务性:全成或全不成

xsReloadQuery 重载

查询意图终态;结果含内容指纹 Revision 与目标描述。

bool xsReloadQuery(XS_ReloadId iId, XS_ReloadResult* pResult);
XS_ReloadResult 字段说明
Id / State意图 ID 与七态之一
Revision不可变输入快照的内容指纹(无配置输入时含脚本指纹)
Target[160] / Message[256]目标描述与结果消息(失败原因)
示例 · 管理路由模式
XS_ReloadId iId = xsReloadHostSubmit(pHost);
XS_ReloadResult tRes;
if ( iId != 0 && xsReloadQuery(iId, &tRes) )
    printf("reload #%llu: %d\n",
        (unsigned long long)tRes.Id, (int)tRes.State);

xsReloadHost / xsReloadServer / xsReloadAll 重载

bool 兼容包装——只表示 Submit 是否返回非零,不等待终态。

bool xsReloadHost(XS_HostInfo* pHost); bool xsReloadServer(const char* sName); bool xsReloadAll(void);
用途:不需要跟踪结果的简单场景

定时器(2)

xsTimerAfter 定时器

一次性定时器,绑定 owner 所属 generation——换代自动作废旧代定时器,不会打进新代。

uint64 xsTimerAfter(XS_HostInfo* pOwner, uint32 iMillisecond, XS_TimerProc proc, void* pUserData);
回调线程:引擎线程返回:0 = 失败;非零 = 定时器 ID
示例
static void OnTick(void* pUserData)
{
    printf("tick: %s\n", (const char*)pUserData);
}
/* ServiceInit 里:5 秒后触发一次 */
(void)xsTimerAfter(pHost, 5000, OnTick, "hello");

xsTimerCancel 定时器

取消定时器。已触发或换代作废的 ID 返回 false。

bool xsTimerCancel(uint64 iTimerId);
返回:false = 已不存在

部署与嵌套(3)

xsAppPath 部署

应用(可执行文件)目录,UTF-8——与配置目录一致,是解析相对路径的锚点。

const char* xsAppPath(void);
所有权:静态借用,无需释放

xsExtensionEnabled 部署

按注册表名(= build 参数名,与启动横幅/--version 一致)查询本变体是否编入某扩展。大小写不敏感;requires 展开的依赖项同样可见;未知名/空串/NULL 返回 false 且不设置错误。编译期等价写法是 #ifdef XS_USE_<名>。

bool xsExtensionEnabled(const char* sName);
示例
if ( xsExtensionEnabled("sqlite") ) {
    /* 本宿主编入了 sqlite,可直接使用 */
    db_open(&db);
} /* 查询不编入则走替代路径 */

xsExtensionCount / xsExtensionName 部署

枚举本变体编入的扩展:count 返回数量,name 按下标取名字(= build 参数名,与启动横幅/--version 同一数据源)。返回静态常量的借用指针,进程期内有效、无需释放;越界返回 NULL 且不设置错误。default 变体下 count 为 0;枚举出的名字喂给 xsExtensionEnabled 必为 true。

uint32 xsExtensionCount(void); const char* xsExtensionName(uint32 iIndex);
示例
for ( uint32 i = 0; i < xsExtensionCount(); i++ ) {
    printf("%u: %s
", i, xsExtensionName(i));
}

xsCreateTCC / xsDestroyTCC 嵌套

创建预置好标准 include/lib 路径与符号导入的嵌套编译器——应用层插件系统的地基。

TCCState* xsCreateTCC(void); void xsDestroyTCC(TCCState* pTcc);
预置:VFS SDK 头 + 宿主符号表变体:扩展符号同样可用

状态交接(1)

xsSwapTake 交接

仅在新代 ServiceInit 内有效:取走旧代 ServiceSwap 导出的快照。无交接数据返回 NULL。

xvalue* xsSwapTake(XS_HostInfo* pHost);
窗口:仅新代 ServiceInit所有权:取走后归应用,xrtValueRelease 释放
示例 · 契约模式
static void ServiceInit(XS_HostInfo* pHost)
{
    xvalue* pState = xsSwapTake(pHost);
    if ( pState != NULL ) {
        G_iCounter = xrtValueInt64(
            xrtValueObjectGet(pState, "counter"));
        xrtValueRelease(pState);   /* 取走后自己释放 */
    }
}

TLS 证书热替换(1)

xsTlsRefresh 证书热替换

对指定 server 重新读取证书并原子热替换:不重启进程、不触发脚本重载、不断开存量连接。新连接立即使用新证书(含 SNI per-host 证书)。与 xacme 组合即全自动续签闭环——签发完成后调用本 API 完成无感切换。

bool xsTlsRefresh(const char* sServerName, char* sErr, size_t iErrCap);
返回:false = 失败(sErr 收原因)证书路径:磁盘优先 → 应用包内兜底
示例 · xacme 续签闭环
/* xacme 签发新证书到磁盘后 */
if ( !xsTlsRefresh("main", aErr, sizeof(aErr)) )
    printf("refresh failed: %s\n", aErr);
/* 成功后新连接即用新证书;存量连接不受影响 */