扩展库 / watch
watch
轮询文件及目录元数据,获取创建、修改、删除事件。
版本 1.0.0 · C / xlang · 无扩展库依赖
当前发布验收保留M2阻断:顶层Watcher在独立程序退出时失败,局部对象与下述普通功能已验证。不能把历史局部门禁通过当作整个包已完成发布签收。
快速开始
import watch
watch.Watcher watcher = watch.create()
int index = watcher.add("config.json")
string event = watcher.poll()
if event != "" then println(event)
watcher.remove(index)
add 允许路径尚不存在;以后创建时可得到 CREATED:path。相对路径按添加时的工作目录固定监视目标,事件仍显示原路径;之后切换工作目录不会改指向。无变化时 poll 返回空串。
接口与范围
| 入口 | 用途 |
|---|---|
watch.create() / watch.exists(path) | 创建监视实例或检查路径;创建分配失败时抛错。 |
Watcher.add(path) / remove(index) | 登记监视路径、删除监视项;空槽位可重用。 |
Watcher.poll() | 每次最多返回一个 CREATED/MODIFIED/DELETED 事件;普通 string 直接接管原生事件分配。 |
Watcher.path(index) / count | 读取路径和活跃监视数量。 |
这是基于 XRT 元数据的轮询实现,不是操作系统通知接口。可用时比较文件身份和创建时间,同大小、保留修改时间的原子替换也能报告变化;目录直接子项同样纳入可用元数据。目录只扫描直接子项,事件指向被监视目录;两次轮询之间的全部中间变化不能还原。目录在元数据查询后、枚举前消失或变为文件时有界重取样一次;权限和内存错误仍返回失败。单个实例不支持多线程同时操作。XL 的路径入口不接受内嵌 NUL,避免 C 字符串截断。
目录子项的元数据按字段顺序哈希,避免相等时间或字段换位互相抵消;包含可用位,不读取未提供字段。访问时间不参与,枚举顺序变化不会造成伪事件。仍是有限64位摘要,不保证无碰撞,也不检查文件内容;每个子项多一次64字节元数据哈希,没有新增堆分配。枚举错误不会被随后的关闭错误覆盖。
C 对照
#include "xrt.h"
#include "watch_native.h"
int main(void)
{
void* watcher = xwatch_create();
if (!watcher) return 1;
int64_t index = xwatch_add(watcher, "config.json");
char* event = xwatch_poll(watcher);
int ok = index >= 0 && event != 0;
xrtFree(event);
xwatch_destroy(watcher);
return ok ? 0 : 1;
}
xwatch_poll 的事件由 C 调用方用 xrtFree 释放,XLang poll() 直接接管;xwatch_path 是借用指针,添加其他监视项或条目表扩容时仍有效,删除对应项或销毁实例后失效,XLang path() 返回独立字符串。公开操作成功时不残留先前失败的 XRT 线程错误;析构不清错。完整双语范例位于 release/extlibs/watch/examples/。
验证状态
2026-10-29:修复目录摘要抵消和关闭覆盖首因;受控12场景8项失败扩为15场景全过,Linux真实同大小、同inode改写也先红后绿。Windows默认49阶段只有最后全局退役失败;Linux sanitizer、八个实际生成原型、两平台各十条普通独立程序与双语输出均先通过。新增顶层正例两平台均JIT0、构建0,独立EXE打印后退出1,明确保留M2红项,不提供包侧绕过。
2026-10-28:修复接管事件后的额外复制在 OOM 时导致事件永久丢失的问题。真实文件事件的逐分配点失败重试、成功后不重复交付和空事件一次结果分配均通过;两平台完整门禁还覆盖 C 边界、Linux ASan/UBSan、目录竞态和双语 JIT/AOT。当前直接返回拥有型 string,不增加私有回滚队列。该保证不等于还原两次元数据轮询之间的所有文件变化。
powershell -NoProfile -ExecutionPolicy Bypass -File release/extlibs/watch/test/check.ps1
bash release/extlibs/watch/test/check.sh
xl run release/extlibs/watch/examples/directory.xl
xl run release/extlibs/watch/examples/directory_c.c
新directory双语范例输出相同三行,展示目录的直接子项同大小改写、目录级MODIFIED和不重复交付。范例调早独占临时文件的初始mtime,不依赖sleep;正常结束清理本次目录。完整门禁当前应因M2返回非零,不能用SkipAot作为发布验收。
C 范例可从仓库根目录直接以 xl run release/extlibs/watch/examples/watch_c.c 运行;Windows/Linux 包门禁均将其与 GCC、XLang 的输出对照。成对范例在独占临时目录验证文件创建、修改、删除事件,并演示索引删除与复用。Windows 严格 GCC、C/XLang 边界、双语范例及带输出 AOT 通过;两平台的定向目录竞争测试覆盖删除、变更类型与真实 I/O 错误,Linux C 文件/目录事件通过 ASan/UBSan,Linux XLang 包内边界用例也通过。文件/工作目录边界用例使用独占临时目录,不再写删固定的 build/test/watch_guard。C 源仅使用公开 XRT 头文件。旧 Windows AOT 缺符号已解除。
2026-10-26 新发布物复核:Windows/Linux 默认包门禁通过 C 边界、目录竞态、XLang JIT/AOT 和公开双语范例;Windows 新增工作目录快照、分配故障及公开语言范例 AOT,两平台新增 C 单文件范例独立 EXE,固定事件输出与 GCC、TCC、XLang 一致。Linux C 侧保留 ASan/UBSan。事件文本由 XLang 直接接管 C 分配,不复制正文。能力范围仍是非递归元数据轮询,不能还原两次轮询之间的全部变化。