Binder中如何实现只有一个IServiceManager对象
[[clang::no_destroy]]
这是Clang的一个属性,它指示编译器在静态对象析构时不要调用delete。这通常用于防止静态对象被意外删除。
std::once_flag
这是一个std::once_flag对象,它是C++11标准库中的一部分,用于确保某个代码块只执行一次。当多个线程尝试设置这个标志时,它确保只有一个线程可以执行该代码块。
\frameworks\native\libs\binder\IServiceManager.cpp
这段代码的目的是确保在程序的整个运行期间只有一个IServiceManager对象存在,并且这个对象是通过一个特定的方式初始化的(即通过获取一个AidlServiceManager对象并使用它来创建一个ServiceManagerShim对象).
[[clang::no_destroy]] static std::once_flag gSmOnce;
[[clang::no_destroy]] static sp<IServiceManager> gDefaultServiceManager;
//这是一个静态的智能指针,指向IServiceManager接口。sp是Android智能指针的一种,用于自动管理对象的生命周期。由于它使用了[[clang::no_destroy]]属性,这意味着这个指针指向的对象不会被自动删除。
//这个函数返回一个指向IServiceManager的智能指针。
sp<IServiceManager> defaultServiceManager()
{
std::call_once(gSmOnce, []() {
sp<AidlServiceManager> sm = nullptr;
while (sm == nullptr) {
sm = interface_cast<AidlServiceManager>(ProcessState::self()->getContextObject(nullptr));
if (sm == nullptr) {
ALOGE("Waiting 1s on context object on %s.", ProcessState::self()->getDriverName().c_str());
sleep(1);
}
}
//1.使用std::call_once确保gSmOnce只初始化一次。如果这个条件满足(也就是说,这个函数第一次被调用),则会执行lambda函数。
//2.这个lambda函数尝试获取一个AidlServiceManager对象。如果获取失败,它会等待1秒并再次尝试,直到成功为止。每次等待和尝试都会输出一个日志信息。
//3.一旦获取到了AidlServiceManager对象,它会创建一个ServiceManagerShim对象,并将这个新创建的对象赋值给gDefaultServiceManager。
gDefaultServiceManager = new ServiceManagerShim(sm);
});
return gDefaultServiceManager;
//函数返回gDefaultServiceManager,这是一个静态的智能指针,指向一个IServiceManager对象。由于它是静态的,所以其生命周期与程序的运行时间相同。
}