用途:在 Filament 的 C++ 多线程类设计与代码编辑中,强制使用 Clang 静态线程安全分析(UTILS_GUARDED_BY 等能力注解),保证状态访问无数据竞争,并统一同步原语的选用。
主要能力与规则:
- 锁原语必须使用 utils::Mutex 与 utils::Condition,filament/ 下的引擎、后端与工具代码禁止使用 std::mutex 或 std::condition_variable。utils::Mutex 可接入 FILAMENT_DEBUG_MUTEX/-u 的编译期锁调试,通过 BFS 维护全局锁依赖图,可捕获锁序反转与自死锁并给出调用栈;std::mutex 不参与该跟踪。
- utils::Condition 以模板方式配合 UniqueLockutils::Mutex 使用,适用于生产者-消费者队列与阻塞等待循环。
- 在 Android 与 Linux 上 utils::Mutex 仅 4 字节(单个原子 futex 字),小于 std::mutex 的 40 字节,适合大量分配或嵌入句柄/围栏的结构。
- C++ 标准 std::mutex 默认不提供优先级继承(PTHREAD_PRIO_NONE),因此相对 utils::Mutex 没有优先级反转保护优势。
使用方式:
- 默认使用 utils::LockGuard const lock(mLock); 建立作用域内只读锁定。仅在传给条件变量 wait(lock) 或需要显式 unlock()/lock() 边界时使用非 const 的 UniqueLock。
- 实例化 LockGuard 或 UniqueLock 的 .cpp 文件必须包含 #include <utils/Mutex.h>。
- 处理 Clang 将 lambda 视为独立上下文导致的误报:推荐模式 A,对条件变量等待谓词的 lambda operator 标注 UTILS_NO_THREAD_SAFETY_ANALYSIS;模式 B,将谓词改写为普通 while 循环,使成员变量处于父函数的锁定作用域内。
限制:所有线程安全注解在单线程配置下会被条件编译移除,标准注解由 UTILS_HAS_THREADING 控制,以避免定义 FILAMENT_SINGLE_THREADED 时编译失败。