本页包含 Fuchsia 在驱动程序运行时中定义 C API 时遵循的一组原则和规则。与其他 API 相比,Fuchsia 对这些 API 更偏重于这些 API,因为它们是驱动程序 ABI 的重要组成部分。
命名
- API 应遵循
<subject>_<verb>[_<object>]
的 Zircon 系统调用命名惯例。- 在
fdf_dispatcher_get_options
的 API 示例中,正文是dispatcher
,动词是get
,对象是options
。 - 不过,并非所有 API 都有对象。在某些情况下,该对象可能是副词(例如
fdf_channel_wait_async
)。 - 仅供测试用的 API 和用于嵌入环境 API 的 API 指的是全局单例对象。
- 在
- API 必须以
fdf_
前缀开头。- 仅供测试用的 API 必须以
fdf_testing_
前缀开头。 - 用于嵌入环境的 API 必须以
fdf_env_
前缀开头。
- 仅供测试用的 API 必须以
- 输出参数必须以
out_
前缀开头。
线程处理
- API 应在注释块中指明其是否处于阻塞状态。
- 阻塞 API 必须验证它们是在已指定
FDF_DISPATCHER_OPTION_ALLOW_SYNC_CALLS
选项的驱动程序运行时调度程序的上下文中调用的。- 不过,
zx_futex_wait
和zx_futex_requeue
是此规则的例外情况,因为它们无法阻塞驱动程序外部的状态,从而避免在驱动程序编写者无法控制的情况下出现死锁的风险。
- 不过,
- API 必须是线程安全的。
- 虽然在不正确的调度程序上下文中调用它们时,它们可能会返回错误,但绝不应以未定义的方式行事。
- 接收回调的 API 应在已同步的2驱动程序运行时调度程序的上下文中提供同步取消语义1。
- 异步取消应会导致调用回调,并且可能会返回错误状态,指示已强制执行前进进度,且不符合触发回调的正常条件。
- API 绝不应根据注册回调函数时所针对的调度程序类型之外的任何其他类型提供有条件同步或异步取消。
物体
- 创建对象的 API 必须具有相应的 API 才能销毁这些对象。
- 返回已创建对象的 API 应返回一个指向对象的不透明指针,并且不描述对象的内部结构。
- 创建对象的 API 应接受
uint32_t options
参数,该参数具有一组可扩展的位标志,以实现可扩展。
参数
- API 应通过指针接受所有非基元参数。
- 接受客户端分配的参数(参数存在时间比函数调用本身更长)的 API 必须执行以下操作:
- 拥有对象及其引用的任何其他对象的完整所有权,前提是这些对象没有自引用(即,也包含在同一分配中)。
- 提供一种机制(例如回调参数),以将对象返回给调用方。
- 提供取消机制,以便在系统正常返回对象之前主动将其返回给调用方。
- 提供一种机制,以允许客户端使用单一分配在对象后面内嵌其他客户端专用上下文。
- 不应假定字符串为以 null 结尾,也不应存在“静态”生命周期。
- 应使用
typedef
为回调参数添加别名为新类型。 - 回调参数应嵌入到
struct
中,以确保它们可以存储在单个分配中。
其他
- API 应该有一个注释块,用于说明其用途、参数、输出和可能的错误。
- 示例为可选,但建议提供。
- 注释块必须使用 Markdown 语法,这有助于生成基于网络的文档。
- API 必须“密集型内存”,也就是说,运行时分配的内存必须由运行时释放,客户端分配的内存必须由客户端释放。
- 此规则的例外情况适用于 arena。
- 如果调用不正确(例如,在参数无效的错误调度程序上),API 应优先返回错误,而不是断言。
- 仅用于测试的 API 必须仅在测试环境中可用。
- 仅限环境的 API 必须只能供驱动程序运行的环境使用,不能供驱动程序本身使用。