diff --git a/core/LocAdapterBase.cpp b/core/LocAdapterBase.cpp index 1b844e57..1e91cf83 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 909b6fea..7ca3ecda 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 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 980d4895..11f6777e 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