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.
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);

View file

@ -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 {

View file

@ -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