Loading media/libstagefright/include/OMXNodeInstance.h +3 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ #define OMX_NODE_INSTANCE_H_ #include <atomic> #include <media/IOMX.h> #include <utils/RefBase.h> #include <utils/threads.h> Loading Loading @@ -111,7 +113,7 @@ private: OMX_HANDLETYPE mHandle; sp<IOMXObserver> mObserver; sp<CallbackDispatcher> mDispatcher; bool mDying; std::atomic_bool mDying; bool mSailed; // configuration is set (no more meta-mode changes) bool mQueriedProhibitedExtensions; SortedVector<OMX_INDEXTYPE> mProhibitedExtensions; Loading media/libstagefright/omx/OMX.cpp +11 −9 Original line number Diff line number Diff line Loading @@ -139,18 +139,20 @@ status_t OMX::freeNode(const sp<OMXNodeInstance> &instance) { if (index < 0) { // This could conceivably happen if the observer dies at roughly the // same time that a client attempts to free the node explicitly. return OK; } mLiveNodes.removeItemsAt(index); } // NOTE: it's guaranteed that this method is called at most once per // instance. ALOGV("freeNode: instance already removed from book-keeping."); } else { mLiveNodes.removeItemsAt(index); IInterface::asBinder(instance->observer())->unlinkToDeath(this); } } OMX_ERRORTYPE err = OMX_ErrorNone; if (instance->handle() != NULL) { err = mMaster->destroyComponentInstance( CHECK(instance->handle() != NULL); OMX_ERRORTYPE err = mMaster->destroyComponentInstance( static_cast<OMX_COMPONENTTYPE *>(instance->handle())); } ALOGV("freeNode: handle destroyed: %p", instance->handle()); return StatusFromOMXError(err); } Loading media/libstagefright/omx/OMXNodeInstance.cpp +7 −7 Original line number Diff line number Diff line Loading @@ -398,15 +398,9 @@ sp<IOMXObserver> OMXNodeInstance::observer() { } status_t OMXNodeInstance::freeNode() { CLOG_LIFE(freeNode, "handle=%p", mHandle); static int32_t kMaxNumIterations = 10; // exit if we have already freed the node if (mHandle == NULL) { return mOwner->freeNode(this); } // Transition the node from its current state all the way down // to "Loaded". // This ensures that all active buffers are properly freed even Loading @@ -416,7 +410,13 @@ status_t OMXNodeInstance::freeNode() { // The code below may trigger some more events to be dispatched // by the OMX component - we want to ignore them as our client // does not expect them. mDying = true; bool expected = false; if (!mDying.compare_exchange_strong(expected, true)) { // exit if we have already freed the node or doing so right now. // NOTE: this ensures that the block below executes at most once. ALOGV("Already dying"); return OK; } OMX_STATETYPE state; CHECK_EQ(OMX_GetState(mHandle, &state), OMX_ErrorNone); Loading services/mediaresourcemanager/ResourceManagerService.cpp +35 −1 Original line number Diff line number Diff line Loading @@ -34,6 +34,31 @@ namespace android { namespace { class DeathNotifier : public IBinder::DeathRecipient { public: DeathNotifier(const wp<ResourceManagerService> &service, int pid, int64_t clientId) : mService(service), mPid(pid), mClientId(clientId) {} virtual void binderDied(const wp<IBinder> & /* who */) override { // Don't check for pid validity since we know it's already dead. sp<ResourceManagerService> service = mService.promote(); if (service == nullptr) { ALOGW("ResourceManagerService is dead as well."); return; } service->removeResource(mPid, mClientId, false); } private: wp<ResourceManagerService> mService; int mPid; int64_t mClientId; }; } // namespace template <typename T> static String8 getString(const Vector<T> &items) { String8 itemsStr; Loading Loading @@ -214,17 +239,25 @@ void ResourceManagerService::addResource( ResourceInfo& info = getResourceInfoForEdit(clientId, client, infos); // TODO: do the merge instead of append. info.resources.appendVector(resources); if (info.deathNotifier == nullptr) { info.deathNotifier = new DeathNotifier(this, pid, clientId); IInterface::asBinder(client)->linkToDeath(info.deathNotifier); } notifyResourceGranted(pid, resources); } void ResourceManagerService::removeResource(int pid, int64_t clientId) { removeResource(pid, clientId, true); } void ResourceManagerService::removeResource(int pid, int64_t clientId, bool checkValid) { String8 log = String8::format( "removeResource(pid %d, clientId %lld)", pid, (long long) clientId); mServiceLog->add(log); Mutex::Autolock lock(mLock); if (!mProcessInfo->isValidPid(pid)) { if (checkValid && !mProcessInfo->isValidPid(pid)) { ALOGE("Rejected removeResource call with invalid pid."); return; } Loading @@ -237,6 +270,7 @@ void ResourceManagerService::removeResource(int pid, int64_t clientId) { ResourceInfos &infos = mMap.editValueAt(index); for (size_t j = 0; j < infos.size(); ++j) { if (infos[j].clientId == clientId) { IInterface::asBinder(infos[j].client)->unlinkToDeath(infos[j].deathNotifier); j = infos.removeAt(j); found = true; break; Loading services/mediaresourcemanager/ResourceManagerService.h +3 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ struct ProcessInfoInterface; struct ResourceInfo { int64_t clientId; sp<IResourceManagerClient> client; sp<IBinder::DeathRecipient> deathNotifier; Vector<MediaResource> resources; }; Loading Loading @@ -70,6 +71,8 @@ public: // Returns true if any resource has been reclaimed, otherwise returns false. virtual bool reclaimResource(int callingPid, const Vector<MediaResource> &resources); void removeResource(int pid, int64_t clientId, bool checkValid); protected: virtual ~ResourceManagerService(); Loading Loading
media/libstagefright/include/OMXNodeInstance.h +3 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ #define OMX_NODE_INSTANCE_H_ #include <atomic> #include <media/IOMX.h> #include <utils/RefBase.h> #include <utils/threads.h> Loading Loading @@ -111,7 +113,7 @@ private: OMX_HANDLETYPE mHandle; sp<IOMXObserver> mObserver; sp<CallbackDispatcher> mDispatcher; bool mDying; std::atomic_bool mDying; bool mSailed; // configuration is set (no more meta-mode changes) bool mQueriedProhibitedExtensions; SortedVector<OMX_INDEXTYPE> mProhibitedExtensions; Loading
media/libstagefright/omx/OMX.cpp +11 −9 Original line number Diff line number Diff line Loading @@ -139,18 +139,20 @@ status_t OMX::freeNode(const sp<OMXNodeInstance> &instance) { if (index < 0) { // This could conceivably happen if the observer dies at roughly the // same time that a client attempts to free the node explicitly. return OK; } mLiveNodes.removeItemsAt(index); } // NOTE: it's guaranteed that this method is called at most once per // instance. ALOGV("freeNode: instance already removed from book-keeping."); } else { mLiveNodes.removeItemsAt(index); IInterface::asBinder(instance->observer())->unlinkToDeath(this); } } OMX_ERRORTYPE err = OMX_ErrorNone; if (instance->handle() != NULL) { err = mMaster->destroyComponentInstance( CHECK(instance->handle() != NULL); OMX_ERRORTYPE err = mMaster->destroyComponentInstance( static_cast<OMX_COMPONENTTYPE *>(instance->handle())); } ALOGV("freeNode: handle destroyed: %p", instance->handle()); return StatusFromOMXError(err); } Loading
media/libstagefright/omx/OMXNodeInstance.cpp +7 −7 Original line number Diff line number Diff line Loading @@ -398,15 +398,9 @@ sp<IOMXObserver> OMXNodeInstance::observer() { } status_t OMXNodeInstance::freeNode() { CLOG_LIFE(freeNode, "handle=%p", mHandle); static int32_t kMaxNumIterations = 10; // exit if we have already freed the node if (mHandle == NULL) { return mOwner->freeNode(this); } // Transition the node from its current state all the way down // to "Loaded". // This ensures that all active buffers are properly freed even Loading @@ -416,7 +410,13 @@ status_t OMXNodeInstance::freeNode() { // The code below may trigger some more events to be dispatched // by the OMX component - we want to ignore them as our client // does not expect them. mDying = true; bool expected = false; if (!mDying.compare_exchange_strong(expected, true)) { // exit if we have already freed the node or doing so right now. // NOTE: this ensures that the block below executes at most once. ALOGV("Already dying"); return OK; } OMX_STATETYPE state; CHECK_EQ(OMX_GetState(mHandle, &state), OMX_ErrorNone); Loading
services/mediaresourcemanager/ResourceManagerService.cpp +35 −1 Original line number Diff line number Diff line Loading @@ -34,6 +34,31 @@ namespace android { namespace { class DeathNotifier : public IBinder::DeathRecipient { public: DeathNotifier(const wp<ResourceManagerService> &service, int pid, int64_t clientId) : mService(service), mPid(pid), mClientId(clientId) {} virtual void binderDied(const wp<IBinder> & /* who */) override { // Don't check for pid validity since we know it's already dead. sp<ResourceManagerService> service = mService.promote(); if (service == nullptr) { ALOGW("ResourceManagerService is dead as well."); return; } service->removeResource(mPid, mClientId, false); } private: wp<ResourceManagerService> mService; int mPid; int64_t mClientId; }; } // namespace template <typename T> static String8 getString(const Vector<T> &items) { String8 itemsStr; Loading Loading @@ -214,17 +239,25 @@ void ResourceManagerService::addResource( ResourceInfo& info = getResourceInfoForEdit(clientId, client, infos); // TODO: do the merge instead of append. info.resources.appendVector(resources); if (info.deathNotifier == nullptr) { info.deathNotifier = new DeathNotifier(this, pid, clientId); IInterface::asBinder(client)->linkToDeath(info.deathNotifier); } notifyResourceGranted(pid, resources); } void ResourceManagerService::removeResource(int pid, int64_t clientId) { removeResource(pid, clientId, true); } void ResourceManagerService::removeResource(int pid, int64_t clientId, bool checkValid) { String8 log = String8::format( "removeResource(pid %d, clientId %lld)", pid, (long long) clientId); mServiceLog->add(log); Mutex::Autolock lock(mLock); if (!mProcessInfo->isValidPid(pid)) { if (checkValid && !mProcessInfo->isValidPid(pid)) { ALOGE("Rejected removeResource call with invalid pid."); return; } Loading @@ -237,6 +270,7 @@ void ResourceManagerService::removeResource(int pid, int64_t clientId) { ResourceInfos &infos = mMap.editValueAt(index); for (size_t j = 0; j < infos.size(); ++j) { if (infos[j].clientId == clientId) { IInterface::asBinder(infos[j].client)->unlinkToDeath(infos[j].deathNotifier); j = infos.removeAt(j); found = true; break; Loading
services/mediaresourcemanager/ResourceManagerService.h +3 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ struct ProcessInfoInterface; struct ResourceInfo { int64_t clientId; sp<IResourceManagerClient> client; sp<IBinder::DeathRecipient> deathNotifier; Vector<MediaResource> resources; }; Loading Loading @@ -70,6 +71,8 @@ public: // Returns true if any resource has been reclaimed, otherwise returns false. virtual bool reclaimResource(int callingPid, const Vector<MediaResource> &resources); void removeResource(int pid, int64_t clientId, bool checkValid); protected: virtual ~ResourceManagerService(); Loading