summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorKevin Tang <zhikait@codeaurora.org>2015-09-11 19:40:25 -0700
committerVamana Murthi <vthuniki@codeaurora.org>2015-11-12 13:06:32 +0530
commit2f74f91ac103afe7d92f594c6c57049e1829c773 (patch)
tree968c55b1019b865cf3b670f02ca6ca083c05c0fd /utils
parentf533181bd69fd32a8a49f4138efbe702f5cdc077 (diff)
downloadgps-2f74f91ac103afe7d92f594c6c57049e1829c773.tar.gz
Crash fix with MsgTask API change
Removed tCreate and tAssociate from MsgTask. LocThread now can optionally take a tCreate method. Associator is replaced with *firstMsg* option to MsgTask, which is a more generic option, that can associate or do other set up job at the create of a MsgTask. The current MsgTask doesn't use tCreate, which exposes a slight time window for Location HAL when its MsgTask is NOT associated to DVM heap but a message delivery to DVM could be attempted during this time. Change-Id: Iafd5b91b693baacb9b7064463f8c44f74026f54c CRs-Fixed: 902350
Diffstat (limited to 'utils')
-rw-r--r--utils/LocSharedLock.h58
-rw-r--r--utils/LocThread.cpp50
-rw-r--r--utils/LocThread.h7
-rw-r--r--utils/LocTimer.cpp22
-rw-r--r--utils/LocTimer.h4
-rw-r--r--utils/MsgTask.cpp48
-rw-r--r--utils/MsgTask.h17
7 files changed, 111 insertions, 95 deletions
diff --git a/utils/LocSharedLock.h b/utils/LocSharedLock.h
new file mode 100644
index 0000000..6b9e27f
--- /dev/null
+++ b/utils/LocSharedLock.h
@@ -0,0 +1,58 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation, nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef __LOC_SHARED_LOCK__
+#define __LOC_SHARED_LOCK__
+
+#include <stddef.h>
+#include <pthread.h>
+
+// This is a utility created for use cases such that there are more than
+// one client who need to share the same lock, but it is not predictable
+// which of these clients is to last to go away. This shared lock deletes
+// itself when the last client calls its drop() method. To add a cient,
+// this share lock's share() method has to be called, so that the obj
+// can maintain an accurate client count.
+class LocSharedLock {
+ uint32_t mRef;
+ pthread_mutex_t mMutex;
+ inline ~LocSharedLock() { pthread_mutex_destroy(&mMutex); }
+public:
+ // first client to create this LockSharedLock
+ inline LocSharedLock() : mRef(1) { pthread_mutex_init(&mMutex, NULL); }
+ // following client(s) are to *share()* this lock created by the first client
+ inline LocSharedLock* share() { mRef++; return this; }
+ // whe a client no longer needs this shared lock, drop() shall be called.
+ inline void drop() { if (0 == --mRef) delete this; }
+ // locking the lock to enter critical section
+ inline void lock() { pthread_mutex_lock(&mMutex); }
+ // unlocking the lock to leave the critical section
+ inline void unlock() { pthread_mutex_unlock(&mMutex); }
+};
+
+#endif //__LOC_SHARED_LOCK__
diff --git a/utils/LocThread.cpp b/utils/LocThread.cpp
index ec1e071..19bf101 100644
--- a/utils/LocThread.cpp
+++ b/utils/LocThread.cpp
@@ -37,12 +37,12 @@ class LocThreadDelegate {
pthread_mutex_t mMutex;
int mRefCount;
~LocThreadDelegate();
- LocThreadDelegate(const char* threadName,
+ LocThreadDelegate(LocThread::tCreate creator, const char* threadName,
LocRunnable* runnable, bool joinable);
void destroy();
public:
- static LocThreadDelegate* create(const char* threadName,
- LocRunnable* runnable, bool joinable);
+ static LocThreadDelegate* create(LocThread::tCreate creator,
+ const char* threadName, LocRunnable* runnable, bool joinable);
void stop();
// bye() is for the parent thread to go away. if joinable,
// parent must stop the spawned thread, join, and then
@@ -62,19 +62,28 @@ public:
// However, upon pthread_create failure, the data members
// must be set to indicate failure, e.g. mRunnable, and
// threashold approprietly for destroy(), e.g. mRefCount.
-LocThreadDelegate::LocThreadDelegate(const char* threadName,
- LocRunnable* runnable, bool joinable) :
- mRunnable(runnable), mJoinable(joinable),
+LocThreadDelegate::LocThreadDelegate(LocThread::tCreate creator,
+ const char* threadName, LocRunnable* runnable, bool joinable) :
+ mRunnable(runnable), mJoinable(joinable), mThandle(NULL),
mMutex(PTHREAD_MUTEX_INITIALIZER), mRefCount(2) {
+
+ // set up thread name, if nothing is passed in
+ if (!threadName) {
+ threadName = "LocThread";
+ }
+
// create the thread here, then if successful
// and a name is given, we set the thread name
- if (!pthread_create(&mThandle, NULL, threadMain, this)) {
+ if (creator) {
+ mThandle = creator(threadName, threadMain, this);
+ } else if (pthread_create(&mThandle, NULL, threadMain, this)) {
+ // pthread_create() failed
+ mThandle = NULL;
+ }
+
+ if (mThandle) {
// set thread name
char lname[16];
- const char* defaultName = "LocThread";
- if (!threadName) {
- threadName = defaultName;
- }
int len = sizeof(lname) - 1;
memcpy(lname, threadName, len);
lname[len] = 0;
@@ -99,11 +108,11 @@ LocThreadDelegate::~LocThreadDelegate() {
}
// factory method so that we could return NULL upon failure
-LocThreadDelegate* LocThreadDelegate::create(const char* threadName,
- LocRunnable* runnable, bool joinable) {
+LocThreadDelegate* LocThreadDelegate::create(LocThread::tCreate creator,
+ const char* threadName, LocRunnable* runnable, bool joinable) {
LocThreadDelegate* thread = NULL;
if (runnable) {
- thread = new LocThreadDelegate(threadName, runnable, joinable);
+ thread = new LocThreadDelegate(creator, threadName, runnable, joinable);
if (thread && !thread->isRunning()) {
thread->destroy();
thread = NULL;
@@ -199,11 +208,14 @@ LocThread::~LocThread() {
}
}
-bool LocThread::start(const char* threadName, LocRunnable* runnable, bool joinable) {
- mThread = LocThreadDelegate::create(threadName, runnable, joinable);
-
- // true only if thread is created successfully
- return (NULL != mThread);
+bool LocThread::start(tCreate creator, const char* threadName, LocRunnable* runnable, bool joinable) {
+ bool success = false;
+ if (!mThread) {
+ mThread = LocThreadDelegate::create(creator, threadName, runnable, joinable);
+ // true only if thread is created successfully
+ success = (NULL != mThread);
+ }
+ return success;
}
void LocThread::stop() {
diff --git a/utils/LocThread.h b/utils/LocThread.h
index 490d309..2a65d8f 100644
--- a/utils/LocThread.h
+++ b/utils/LocThread.h
@@ -30,6 +30,7 @@
#define __LOC_THREAD__
#include <stddef.h>
+#include <pthread.h>
// abstract class to be implemented by client to provide a runnable class
// which gets scheduled by LocThread
@@ -64,6 +65,7 @@ public:
inline LocThread() : mThread(NULL) {}
virtual ~LocThread();
+ typedef pthread_t (*tCreate)(const char* name, void* (*start)(void*), void* arg);
// client starts thread with a runnable, which implements
// the logics to fun in the created thread context.
// The thread could be either joinable or detached.
@@ -74,7 +76,10 @@ public:
// returns true. Else it is client's responsibility
// to delete the object
// Returns 0 if success; false if failure.
- bool start(const char* threadName, LocRunnable* runnable, bool joinable = true);
+ bool start(tCreate creator, const char* threadName, LocRunnable* runnable, bool joinable = true);
+ inline bool start(const char* threadName, LocRunnable* runnable, bool joinable = true) {
+ return start(NULL, threadName, runnable, joinable);
+ }
// NOTE: if this is a joinable thread, this stop may block
// for a while until the thread is joined.
diff --git a/utils/LocTimer.cpp b/utils/LocTimer.cpp
index 0f698c5..c992e7c 100644
--- a/utils/LocTimer.cpp
+++ b/utils/LocTimer.cpp
@@ -37,7 +37,7 @@
#include <LocTimer.h>
#include <LocHeap.h>
#include <LocThread.h>
-#include <pthread.h>
+#include <LocSharedLock.h>
#include <MsgTask.h>
#ifdef __HOST_UNIT_TEST__
@@ -46,22 +46,6 @@
#define CLOCK_BOOTTIME_ALARM CLOCK_MONOTONIC
#endif
-using namespace loc_core;
-
-// a shared lock until, place it here for now.
-class LocUtilSharedLock {
- uint32_t mRef;
- pthread_mutex_t mMutex;
- inline ~LocUtilSharedLock() { pthread_mutex_destroy(&mMutex); }
-public:
- inline LocUtilSharedLock() : mRef(1) { pthread_mutex_init(&mMutex, NULL); }
- inline LocUtilSharedLock* share() { mRef++; return this; }
- inline void drop() { if (0 == --mRef) delete this; }
- inline void lock() { pthread_mutex_lock(&mMutex); }
- inline void unlock() { pthread_mutex_unlock(&mMutex); }
-};
-
-
/*
There are implementations of 5 classes in this file:
LocTimer, LocTimerDelegate, LocTimerContainer, LocTimerPollTask, LocTimerWrapper
@@ -191,7 +175,7 @@ class LocTimerDelegate : public LocRankable {
friend class LocTimerContainer;
friend class LocTimer;
LocTimer* mClient;
- LocUtilSharedLock* mLock;
+ LocSharedLock* mLock;
struct timespec mFutureTime;
LocTimerContainer* mContainer;
// not a complete obj, just ctor for LocRankable comparisons
@@ -548,7 +532,7 @@ void LocTimerDelegate::expire() {
/***************************LocTimer methods***************************/
-LocTimer::LocTimer() : mTimer(NULL), mLock(new LocUtilSharedLock()) {
+LocTimer::LocTimer() : mTimer(NULL), mLock(new LocSharedLock()) {
}
LocTimer::~LocTimer() {
diff --git a/utils/LocTimer.h b/utils/LocTimer.h
index 9606fe5..c146852 100644
--- a/utils/LocTimer.h
+++ b/utils/LocTimer.h
@@ -35,14 +35,14 @@
// opaque class to provide service implementation.
class LocTimerDelegate;
-class LocUtilSharedLock;
+class LocSharedLock;
// LocTimer client must extend this class and implementthe callback.
// start() / stop() methods are to arm / disarm timer.
class LocTimer
{
LocTimerDelegate* mTimer;
- LocUtilSharedLock* mLock;
+ LocSharedLock* mLock;
// don't really want mLock to be manipulated by clients, yet LocTimer
// has to have a reference to the lock so that the delete of LocTimer
// and LocTimerDelegate can work together on their share resources.
diff --git a/utils/MsgTask.cpp b/utils/MsgTask.cpp
index 8b645dd..fdb1102 100644
--- a/utils/MsgTask.cpp
+++ b/utils/MsgTask.cpp
@@ -36,12 +36,19 @@
#include <log_util.h>
#include <loc_log.h>
-namespace loc_core {
-
static void LocMsgDestroy(void* msg) {
delete (LocMsg*)msg;
}
+MsgTask::MsgTask(LocThread::tCreate tCreator,
+ const char* threadName, bool joinable) :
+ mQ(msg_q_init2()), mThread(new LocThread()) {
+ if (!mThread->start(tCreator, threadName, this, joinable)) {
+ delete mThread;
+ mThread = NULL;
+ }
+}
+
MsgTask::MsgTask(const char* threadName, bool joinable) :
mQ(msg_q_init2()), mThread(new LocThread()) {
if (!mThread->start(threadName, this, joinable)) {
@@ -93,40 +100,3 @@ bool MsgTask::run() {
return true;
}
-
-// TODO: remove the below in the next patch
-void MsgTask::associate(tAssociate tAssociator) const {
- struct LocAssociateMsg : public LocMsg {
- tAssociate mAssociator;
- LocAssociateMsg(tAssociate associator) :
- mAssociator(associator) {}
- inline virtual void proc() const {
- static bool sAssociated = false;
- if (!sAssociated) {
- sAssociated = true;
- mAssociator();
- }
- }
- };
- sendMsg(new LocAssociateMsg(tAssociator));
-}
-
-MsgTask::MsgTask(tCreate tCreator, const char* threadName) :
- mQ(msg_q_init2()), mThread(new LocThread()) {
- if (!mThread->start(threadName, this, false)) {
- delete mThread;
- mThread = NULL;
- }
-}
-
-MsgTask::MsgTask(tAssociate tAssociator, const char* threadName) :
- mQ(msg_q_init2()), mThread(new LocThread()) {
- if (!mThread->start(threadName, this, false)) {
- delete mThread;
- mThread = NULL;
- } else {
- associate(tAssociator);
- }
-}
-
-} // namespace loc_core
diff --git a/utils/MsgTask.h b/utils/MsgTask.h
index c397ee1..9eb1f56 100644
--- a/utils/MsgTask.h
+++ b/utils/MsgTask.h
@@ -30,10 +30,6 @@
#define __MSG_TASK__
#include <LocThread.h>
-// TODO: remove this include in the next patch
-#include <pthread.h>
-
-namespace loc_core {
struct LocMsg {
inline LocMsg() {}
@@ -42,13 +38,14 @@ struct LocMsg {
inline virtual void log() const {}
};
-class MsgTask : public LocRunnable{
+class MsgTask : public LocRunnable {
const void* mQ;
LocThread* mThread;
friend class LocThreadDelegate;
protected:
virtual ~MsgTask();
public:
+ MsgTask(LocThread::tCreate tCreator, const char* threadName = NULL, bool joinable = true);
MsgTask(const char* threadName = NULL, bool joinable = true);
// this obj will be deleted once thread is deleted
void destroy();
@@ -65,16 +62,6 @@ public:
// The method to be run after thread loop (conditionally repeatedly)
// calls run()
inline virtual void postrun() {}
-
- // TODO: remove the below in the next patch
- typedef void* (*tStart)(void*);
- typedef pthread_t (*tCreate)(const char* name, tStart start, void* arg);
- typedef int (*tAssociate)();
- MsgTask(tCreate tCreator, const char* threadName);
- MsgTask(tAssociate tAssociator, const char* threadName);
- void associate(tAssociate tAssociator) const;
};
-} // namespace loc_core
-
#endif //__MSG_TASK__