service启动的进程无法获取进程创建的mutex

本文介绍了一种使用Mutex来确保进程单实例运行的方法,并解决了不同用户权限下Mutex访问问题。通过设置安全属性,使得由system用户启动的服务进程能够正确判断是否已有实例运行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

当一个进程被某个service启动后,他的启动用户为system,如果这个进程是希望单实例运行的,判断如下


hMutex = CreateMutex(NULL, FALSE, "Name");

if( GetLastError == ERROR_ALREADY_EXISTS)

{

  已经存在运行实例

}


如果启动这个进程的是普通用户,比如administrator,那么在执行到CreateMutex时,GetLastError返回的是ERROR_ACCESS_DENIED,被禁止访问,hMutex返回0,这个时候将对启动多个实例了。

是否做ERROR_ACCESS_DENIED判断???



可以如下方式建立Mutex,可以避免以上问题。

var
  hMutex: THandle;
  sa: _SECURITY_ATTRIBUTES;
  sd: SECURITY_DESCRIPTOR;
begin
  InitializeSecurityDescriptor(@sd, SECURITY_DESCRIPTOR_REVISION);
  SetSecurityDescriptorDacl(@sd, True, nil, False);
  sa.nLength := SizeOf(_SECURITY_ATTRIBUTES);
  sa.bInheritHandle := True;
  sa.lpSecurityDescriptor := @sd;
  hMutex := CreateMutex(@sa, False, PChar('name'));

end;

SYSTEM下建立的默认描述符普通用户无法访问。

#include "OplusGameOpt.h" #include <math.h> #include <stdlib.h> #include <utils/Log.h> #include <utils/String8.h> #include <android/binder_manager.h> #include <android/binder_process.h> #include <log/log.h> #include <android-base/logging.h> using namespace std; using namespace android; using android::hidl::base::V1_0::IBase; using ::android::sp; using ::aidl::vendor::oplus::hardware::gameopt::IGameOptHalService; template<typename T> using Return = hardware::Return<T>; ANDROID_SINGLETON_STATIC_INSTANCE(OplusGameOpt); OplusGameOpt::OplusGameOpt() { ALOGI("OplusGameOpt init"); Mutex::Autolock _l(mLock); checkService(); } OplusGameOpt::~OplusGameOpt() { delete mDeathMonitor; mDeathMonitor = nullptr; } bool OplusGameOpt::checkService() { if (mService != nullptr) { return true; } else { std::string aidl_instance = std::string() + IGameOptHalService::descriptor + "/default"; mService = IGameOptHalService::fromBinder(ndk::SpAIBinder(AServiceManager_checkService(aidl_instance.c_str()))); if (mService == nullptr) { ALOGE("unable to get OplusGameOpt service"); } else { ALOGD("succeed in getting OplusGameOpt service"); if (mDeathMonitor == nullptr) { ALOGD("create DeathMonitor()"); mDeathMonitor = new DeathMonitor(); } else { ALOGD("delete old DeathMonitor() and create a new one"); delete mDeathMonitor; mDeathMonitor = nullptr; mDeathMonitor = new DeathMonitor(); } mDeathMonitor->init(mService); return true; } } mService = nullptr; return false; } void OplusGameOpt::handleServiceDied() { Mutex::Autolock _l(mLock); mService = NULL; } void OplusGameOpt::notifySFBufferProduced(int32_t bufferNum, int64_t timeStamp) { Mutex::Autolock _l(mLock); if (!checkService()) { ALOGE("OplusGameOpt notifySFBufferProduced check service failed"); return; } ndk::ScopedAStatus ret = mService->notifySFBufferProduced(bufferNum, timeStamp); if (!ret.isOk()) { ALOGE("OplusGameOpt notifySFBufferProduced failed: %s", ret.getDescription().c_str()); } } void OplusGameOpt::notifyGameInfo(int32_t type, const string& data) { Mutex::Autolock _l(mLock); if (!checkService()) { ALOGE("OplusGameOpt notifyGameInfo check service failed"); return; } ndk::ScopedAStatus ret = mService->notifyGameInfo(type, data); if (!ret.isOk()) { ALOGE("OplusGameOpt notifyGameInfo failed: %s", ret.getDescription().c_str()); } } DeathMonitor::DeathMonitor(): mDeathRecipient(AIBinder_DeathRecipient_new(DeathMonitor::serviceDied)) { } DeathMonitor::~DeathMonitor() { //AIBinder_DeathRecipient_delete(mDeathRecipient.get()); } void DeathMonitor::init(std::shared_ptr<::aidl::vendor::oplus::hardware::gameopt::IGameOptHalService> obj) { mObj = obj; if (mObj == nullptr) { return; } auto status = ::ndk::ScopedAStatus::fromStatus(::AIBinder_linkToDeath( mObj->asBinder().get(), mDeathRecipient.get(), this)); if (!status.isOk()) { ALOGE("AIBinder_linkToDeath failed"); } } void DeathMonitor::serviceDied(void* cookie) { DeathMonitor* monitor = static_cast<DeathMonitor*>(cookie); monitor->serviceDied(); } void DeathMonitor::serviceDied() { if (mObj != nullptr) { auto ret = ::ndk::ScopedAStatus::fromStatus(::AIBinder_unlinkToDeath( mObj->asBinder().get(), mDeathRecipient.get(), this)); if (!ret.isOk()) { ALOGE("AIBinder_unlinkToDeath failed"); } } mObj = nullptr; OplusGameOpt::getInstance().handleServiceDied(); } 解释代码含义
最新发布
03-08
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值