summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWei Chen <weic@codeaurora.org>2019-10-01 14:18:29 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2019-10-24 09:44:30 -0700
commit5c568ca1bdd64c4de4a29695457db6bd81d0f5d8 (patch)
tree27609c38dcd14bb2dc63224d54c5a50580dd147b
parent91c053b7722254be636445ac4f3b2498cecd5c2d (diff)
downloadgps-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.cpp11
-rw-r--r--core/LocAdapterBase.h24
-rw-r--r--gnss/GnssAdapter.cpp11
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