include/linux/cleanup.h
RAII 是使用 scope 作为自动释放资源时机的机制,广泛应用在 C++、Rust 这样的高级语言中。C 缺乏相应的析构函数的机制来做这件事情。
GCC 扩展是实现这一机制的方法,绕开 C 标准的 GCC 扩展本质上不仅适用于 GCC,Clang 的支持也是同步的,对于 Linux Kernel 来说,GCC/Clang 就已经能够完全满足需求了。
Linux 采用宏提供了一系列的 RAII 式的 API(Linux 6.5+),在 Mutex、fd 子模块中首先开始推广。
Cleanup functions §
首先需要在 C 中提供析构函数的抽象,这是由 GCC 扩展 __attribute__((__cleanup(func)))
实现的,Linux 提供了一个简单的包装:
但是,有时候我们想要把一个变量 move 出去,而非在当前作用域结束就 free 掉,这时候就可以采用下面的 API:
例子:
From cleanup to class §
直接使用 cleanup 的操作有时候非常容易出错,比如 return_ptr
的返回值没有被标注 __free
就容易导致资源泄漏。进而 Linux 提供了更高级的封装—— Class
:
class 用来表达资源的所有者,负责资源的申请和释放,使用 DEFINE_CLASS
会自动生成构造函数和析构函数。接下来使用 CLASS
宏构造变量:
例子:
上述的宏展开得到:
Lock guard §
这一机制在 Mutex 中非常实用,因为可能在不同的情况下产生错误,现有的 Linux 代码都采用 goto 来释放资源,则显得略显繁杂:
在采用了新的 RAII 机制之后,可以使这一结构变得非常简洁:
Locking 模块提供了以下的 API:
进而 mutex 可以定义为:
使用的方式也非常简单:
What’s Next §
libcsptr