c++ - 基于 IOKit 的 kext 驱动程序中的单例类
问题描述
我有一个类维护class IOSharedDataQueue : public IODataQueue
IOKit 对象类型的实例。
该类与主类的各种方法解耦并调用,主类是基于 IOKit 的类(派生自IOService
)。
在尝试将此类转换为单例时,我添加了getInstance
具有以下实现的函数:
myclass& myclass::getInstance()
{
static myclass instance;
return instance;
}
但是,似乎 c++11 初始化单例的方式应该在 IOKit 编译器中工作,并且 Xcode 产生以下错误:
This initialization requires a guard variable, which the kernel does not support
问题是,它适用于不包含基于 IOKIt 的对象的类。
也许有人遇到过这个问题,我还没有看到任何关于这个限制的文档。
编辑 :
我发现如果我的类不以任何方式包含任何 IOResources 对象,它可以设计为带有保护变量的单例。
但是,我仍然希望能够创建一些简单且包含的包装器,以便在整个 IOKit 项目中使用,而无需传递指针。
解决方案
IOKit 对象是引用计数的,并且必须始终new
通过调用来实例化和销毁release()
。因此,不管 kexts 中没有线程安全的静态初始化器这一事实,您都不应该静态分配 IOKit 对象。您可以使用原子指针或基于锁的机制在第一次调用函数时实例化对象,或在固定时间创建实例。
无论如何,作为显式单例的 IOService 是可疑的 - 您确定不应该使用基于 IOResource 的 IOKit 匹配来创建单个实例吗?
我建议的内容如下:
static myclass* singleton_instance;
myclass* myclass::getInstance()
{
if (singleton_instance == nullptr)
{
myclass* new_instance = new myclass();
new_instance->init();
if (!OSCompareAndSwapPtr(nullptr, new_instance, &singleton_instance))
{
new_instance->release();
}
}
return singleton_instance;
}
// TODO: release singleton_instance when kext unloads
推荐阅读
- mysql - 在 MySQL 表的基于范围的分区中确定分区键
- python - 如何解决在 Django 中执行 manage.py runserver 命令时的错误原因?
- flutter - Flutter:如何以编程方式打开抽屉
- spring-boot - 自动部署 Spring Boot 应用程序文件更改,无需手动重启
- intellij-idea - IntelliJ 不允许某些按键
- r - R Studio 中的动态函数 - 在 R Shiny 上部署
- python - 由于 Protobuf 错误,无法使用 Pycharm 安装 Tensorflow
- javascript - react-bootstrap 组件开关不起作用
- javascript - 使用闭包编译器 linter 抑制单个警告
- android - 我可以在不运行真机或模拟器的情况下在 android studio 上测试代码吗?