diff options
author | Wei Chen <weic@codeaurora.org> | 2019-10-01 14:18:29 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2019-10-24 09:44:30 -0700 |
commit | 5c568ca1bdd64c4de4a29695457db6bd81d0f5d8 (patch) | |
tree | 27609c38dcd14bb2dc63224d54c5a50580dd147b | |
parent | 91c053b7722254be636445ac4f3b2498cecd5c2d (diff) | |
download | gps-5c568ca1bdd64c4de4a29695457db6bd81d0f5d8.tar.gz |
GNSS adapter: fix a race condition
Fix the race condition that handleEngineUp gets called before
GNSS adapter constructor finishes
CRs-fixed: 2538904
Change-Id: I0946dd44ce3a4b03f2c8a45a855bbfbd4b7b8468
-rw-r--r-- | core/LocAdapterBase.cpp | 11 | ||||
-rw-r--r-- | core/LocAdapterBase.h | 24 | ||||
-rw-r--r-- | gnss/GnssAdapter.cpp | 11 |
3 files changed, 39 insertions, 7 deletions
diff --git a/core/LocAdapterBase.cpp b/core/LocAdapterBase.cpp index 1b844e5..1e91cf8 100644 --- a/core/LocAdapterBase.cpp +++ b/core/LocAdapterBase.cpp @@ -43,13 +43,20 @@ namespace loc_core { // the right locApi should get created. LocAdapterBase::LocAdapterBase(const LOC_API_ADAPTER_EVENT_MASK_T mask, ContextBase* context, bool isMaster, - LocAdapterProxyBase *adapterProxyBase) : + LocAdapterProxyBase *adapterProxyBase, + bool waitForDoneInit) : mIsMaster(isMaster), mEvtMask(mask), mContext(context), mLocApi(context->getLocApi()), mLocAdapterProxyBase(adapterProxyBase), mMsgTask(context->getMsgTask()), mIsEngineCapabilitiesKnown(ContextBase::sIsEngineCapabilitiesKnown) { - mLocApi->addAdapter(this); + LOC_LOGd("waitForDoneInit: %d", waitForDoneInit); + if (!waitForDoneInit) { + mLocApi->addAdapter(this); + mAdapterAdded = true; + } else { + mAdapterAdded = false; + } } uint32_t LocAdapterBase::mSessionIdCounter(1); diff --git a/core/LocAdapterBase.h b/core/LocAdapterBase.h index 909b6fe..7ca3ecd 100644 --- a/core/LocAdapterBase.h +++ b/core/LocAdapterBase.h @@ -70,9 +70,11 @@ protected: LocApiBase* mLocApi; LocAdapterProxyBase* mLocAdapterProxyBase; const MsgTask* mMsgTask; + bool mAdapterAdded; + inline LocAdapterBase(const MsgTask* msgTask) : mIsMaster(false), mEvtMask(0), mContext(NULL), mLocApi(NULL), - mLocAdapterProxyBase(NULL), mMsgTask(msgTask) {} + mLocAdapterProxyBase(NULL), mMsgTask(msgTask), mAdapterAdded(false) {} /* ==== CLIENT ========================================================================= */ typedef std::map<LocationAPI*, LocationCallbacks> ClientDataMap; @@ -89,9 +91,27 @@ protected: public: inline virtual ~LocAdapterBase() { mLocApi->removeAdapter(this); } + // When waitForDoneInit is not specified or specified as false, + // handleEngineUpEvent may be called on the child adapter object from + // a different thread before the constructor of the child + // object finishes. + // + // If the handleEngineUpEvent relies on member variables of the constructor + // of the child adapter to be initialized first, we need to specify the + // waitForDoneInit to *TRUE* to delay handleEngineUpEvent to get called + // until when the child adapter finishes its initialization and notify + // LocAdapterBase via doneInit method. LocAdapterBase(const LOC_API_ADAPTER_EVENT_MASK_T mask, ContextBase* context, bool isMaster = false, - LocAdapterProxyBase *adapterProxyBase = NULL); + LocAdapterProxyBase *adapterProxyBase = NULL, + bool waitForDoneInit = false); + + inline void doneInit() { + if (!mAdapterAdded) { + mLocApi->addAdapter(this); + mAdapterAdded = true; + } + } inline LOC_API_ADAPTER_EVENT_MASK_T checkMask(LOC_API_ADAPTER_EVENT_MASK_T mask) const { diff --git a/gnss/GnssAdapter.cpp b/gnss/GnssAdapter.cpp index 980d489..11f6777 100644 --- a/gnss/GnssAdapter.cpp +++ b/gnss/GnssAdapter.cpp @@ -65,9 +65,10 @@ static void agpsCloseResultCb (bool isSuccess, AGpsExtType agpsType, void* userD GnssAdapter::GnssAdapter() : LocAdapterBase(0, LocContext::getLocContext(NULL, - NULL, - LocContext::mLocationHalName, - false), true, nullptr), + NULL, + LocContext::mLocationHalName, + false), + true, nullptr, true), mEngHubProxy(new EngineHubProxyBase()), mLocPositionMode(), mGnssSvIdUsedInPosition(), @@ -127,6 +128,10 @@ GnssAdapter::GnssAdapter() : readConfigCommand(); initDefaultAgpsCommand(); initEngHubProxyCommand(); + + // at last step, let us inform adapater base that we are done + // with initialization, e.g.: ready to process handleEngineUpEvent + doneInit(); } void |