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
This commit is contained in:
Wei Chen 2019-10-01 14:18:29 -07:00 committed by Gerrit - the friendly Code Review server
parent 91c053b772
commit 5c568ca1bd
3 changed files with 39 additions and 7 deletions

View file

@ -43,13 +43,20 @@ namespace loc_core {
// the right locApi should get created. // the right locApi should get created.
LocAdapterBase::LocAdapterBase(const LOC_API_ADAPTER_EVENT_MASK_T mask, LocAdapterBase::LocAdapterBase(const LOC_API_ADAPTER_EVENT_MASK_T mask,
ContextBase* context, bool isMaster, ContextBase* context, bool isMaster,
LocAdapterProxyBase *adapterProxyBase) : LocAdapterProxyBase *adapterProxyBase,
bool waitForDoneInit) :
mIsMaster(isMaster), mEvtMask(mask), mContext(context), mIsMaster(isMaster), mEvtMask(mask), mContext(context),
mLocApi(context->getLocApi()), mLocAdapterProxyBase(adapterProxyBase), mLocApi(context->getLocApi()), mLocAdapterProxyBase(adapterProxyBase),
mMsgTask(context->getMsgTask()), mMsgTask(context->getMsgTask()),
mIsEngineCapabilitiesKnown(ContextBase::sIsEngineCapabilitiesKnown) mIsEngineCapabilitiesKnown(ContextBase::sIsEngineCapabilitiesKnown)
{ {
LOC_LOGd("waitForDoneInit: %d", waitForDoneInit);
if (!waitForDoneInit) {
mLocApi->addAdapter(this); mLocApi->addAdapter(this);
mAdapterAdded = true;
} else {
mAdapterAdded = false;
}
} }
uint32_t LocAdapterBase::mSessionIdCounter(1); uint32_t LocAdapterBase::mSessionIdCounter(1);

View file

@ -70,9 +70,11 @@ protected:
LocApiBase* mLocApi; LocApiBase* mLocApi;
LocAdapterProxyBase* mLocAdapterProxyBase; LocAdapterProxyBase* mLocAdapterProxyBase;
const MsgTask* mMsgTask; const MsgTask* mMsgTask;
bool mAdapterAdded;
inline LocAdapterBase(const MsgTask* msgTask) : inline LocAdapterBase(const MsgTask* msgTask) :
mIsMaster(false), mEvtMask(0), mContext(NULL), mLocApi(NULL), mIsMaster(false), mEvtMask(0), mContext(NULL), mLocApi(NULL),
mLocAdapterProxyBase(NULL), mMsgTask(msgTask) {} mLocAdapterProxyBase(NULL), mMsgTask(msgTask), mAdapterAdded(false) {}
/* ==== CLIENT ========================================================================= */ /* ==== CLIENT ========================================================================= */
typedef std::map<LocationAPI*, LocationCallbacks> ClientDataMap; typedef std::map<LocationAPI*, LocationCallbacks> ClientDataMap;
@ -89,9 +91,27 @@ protected:
public: public:
inline virtual ~LocAdapterBase() { mLocApi->removeAdapter(this); } 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, LocAdapterBase(const LOC_API_ADAPTER_EVENT_MASK_T mask,
ContextBase* context, bool isMaster = false, 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 inline LOC_API_ADAPTER_EVENT_MASK_T
checkMask(LOC_API_ADAPTER_EVENT_MASK_T mask) const { checkMask(LOC_API_ADAPTER_EVENT_MASK_T mask) const {

View file

@ -67,7 +67,8 @@ GnssAdapter::GnssAdapter() :
LocContext::getLocContext(NULL, LocContext::getLocContext(NULL,
NULL, NULL,
LocContext::mLocationHalName, LocContext::mLocationHalName,
false), true, nullptr), false),
true, nullptr, true),
mEngHubProxy(new EngineHubProxyBase()), mEngHubProxy(new EngineHubProxyBase()),
mLocPositionMode(), mLocPositionMode(),
mGnssSvIdUsedInPosition(), mGnssSvIdUsedInPosition(),
@ -127,6 +128,10 @@ GnssAdapter::GnssAdapter() :
readConfigCommand(); readConfigCommand();
initDefaultAgpsCommand(); initDefaultAgpsCommand();
initEngHubProxyCommand(); initEngHubProxyCommand();
// at last step, let us inform adapater base that we are done
// with initialization, e.g.: ready to process handleEngineUpEvent
doneInit();
} }
void void