nanohub HAL: use STL thread model

Change-Id: I8114d1b4cd46399b4ca2cca02667488853846d8a
diff --git a/contexthubhal/nanohubhal.cpp b/contexthubhal/nanohubhal.cpp
index d53a16c..4f0c10b 100644
--- a/contexthubhal/nanohubhal.cpp
+++ b/contexthubhal/nanohubhal.cpp
@@ -18,7 +18,6 @@
 
 #include <fcntl.h>
 #include <poll.h>
-#include <pthread.h>
 #include <unistd.h>
 #include <sys/inotify.h>
 #include <sys/types.h>
@@ -176,13 +175,7 @@
     mMsgCbkFunc(0, &msg, mMsgCbkData);
 }
 
-void* NanoHub::run(void *data)
-{
-    NanoHub *self = static_cast<NanoHub*>(data);
-    return self->doRun();
-}
-
-void* NanoHub::doRun()
+void* NanoHub::run()
 {
     enum {
         IDX_NANOHUB,
@@ -279,18 +272,9 @@
         goto fail_pipe;
     }
 
-    if (pthread_create(&mWorkerThread, NULL, &NanoHub::run, this)) {
-        ALOGE("failed to spawn worker thread");
-        ret = -errno;
-        goto fail_thread;
-    }
-
+    mPollThread = std::thread([this] { run(); });
     return 0;
 
-fail_thread:
-    close(mThreadClosingPipe[0]);
-    close(mThreadClosingPipe[1]);
-
 fail_pipe:
     close(mFd);
 
@@ -306,7 +290,9 @@
     while(write(mThreadClosingPipe[1], &zero, 1) != 1);
 
     //wait
-    (void)pthread_join(mWorkerThread, NULL);
+    if (mPollThread.joinable()) {
+        mPollThread.join();
+    }
 
     //cleanup
     ::close(mThreadClosingPipe[0]);
@@ -323,7 +309,7 @@
         return -ENODEV;
     }
 
-    Mutex::Autolock _l(mLock);
+    std::lock_guard<std::mutex> _l(mLock);
     int ret = 0;
 
     if (!mMsgCbkFunc && !cbk) { //we're off and staying off - do nothing
@@ -356,7 +342,7 @@
     }
 
     int ret = 0;
-    Mutex::Autolock _l(mLock);
+    std::lock_guard<std::mutex> _l(mLock);
 
     if (!mMsgCbkFunc) {
         ALOGW("refusing to send a message when nobody around to get a reply!");
diff --git a/contexthubhal/nanohubhal.h b/contexthubhal/nanohubhal.h
index 9014a5e..0ebe401 100644
--- a/contexthubhal/nanohubhal.h
+++ b/contexthubhal/nanohubhal.h
@@ -17,10 +17,10 @@
 #ifndef _NANOHUB_HAL_H_
 #define _NANOHUB_HAL_H_
 
-#include <pthread.h>
+#include <mutex>
+#include <thread>
 
 #include <hardware/context_hub.h>
-#include <utils/Mutex.h>
 
 #define NANOAPP_VENDOR_GOOGLE NANOAPP_VENDOR("Googl")
 
@@ -46,12 +46,12 @@
 } __attribute__((packed));
 
 class NanoHub {
-    Mutex mLock;
+    std::mutex mLock;
+    std::thread mPollThread;
     context_hub_callback *mMsgCbkFunc;
     int mThreadClosingPipe[2];
     int mFd; // [0] is read end
     void * mMsgCbkData;
-    pthread_t mWorkerThread;
 
     NanoHub() {
         reset();
@@ -63,11 +63,9 @@
         mFd = -1;
         mMsgCbkData = nullptr;
         mMsgCbkFunc = nullptr;
-        mWorkerThread = 0;
     }
 
-    static void* run(void *);
-    void* doRun();
+    void* run();
 
     int openHub();
     int closeHub();
diff --git a/contexthubhal/system_comms.cpp b/contexthubhal/system_comms.cpp
index e847d24..19cbef6 100644
--- a/contexthubhal/system_comms.cpp
+++ b/contexthubhal/system_comms.cpp
@@ -95,8 +95,9 @@
     return NanoHub::sendToDevice(&getSystem()->mHostIfAppName, data, len);
 }
 
-int SystemComm::AppInfoSession::setup(const hub_message_t *) {
-    Mutex::Autolock _l(mLock);
+int SystemComm::AppInfoSession::setup(const hub_message_t *)
+{
+    std::lock_guard<std::mutex> _l(mLock);
     int suggestedSize = mAppInfo.size() ? mAppInfo.size() : 20;
 
     mAppInfo.clear();
@@ -118,7 +119,7 @@
 
 int SystemComm::AppInfoSession::handleRx(MessageBuf &buf)
 {
-    Mutex::Autolock _l(mLock);
+    std::lock_guard<std::mutex> _l(mLock);
 
     NanohubRsp rsp(buf, true);
     if (rsp.cmd != NANOHUB_QUERY_APPS) {
@@ -174,8 +175,9 @@
     return sendToSystem(buf.getData(), buf.getPos());
 }
 
-int SystemComm::GlobalSession::setup(const hub_message_t *) {
-    Mutex::Autolock _l(mLock);
+int SystemComm::GlobalSession::setup(const hub_message_t *)
+{
+    std::lock_guard<std::mutex> _l(mLock);
 
     setState(SESSION_USER);
 
@@ -184,7 +186,7 @@
 
 int SystemComm::GlobalSession::handleRx(MessageBuf &buf)
 {
-    Mutex::Autolock _l(mLock);
+    std::lock_guard<std::mutex> _l(mLock);
 
     NanohubRsp rsp(buf);
     if (rsp.cmd != NANOHUB_REBOOT) {
@@ -199,7 +201,7 @@
 
 int SystemComm::MemInfoSession::setup(const hub_message_t *)
 {
-    Mutex::Autolock _l(mLock);
+    std::lock_guard<std::mutex> _l(mLock);
     char data[MAX_RX_PACKET];
     MessageBuf buf(data, sizeof(data));
     buf.writeU8(NANOHUB_QUERY_MEMINFO);
@@ -210,7 +212,7 @@
 
 int SystemComm::MemInfoSession::handleRx(MessageBuf &buf)
 {
-    Mutex::Autolock _l(mLock);
+    std::lock_guard<std::mutex> _l(mLock);
     NanohubRsp rsp(buf, true);
 
     if (rsp.cmd != NANOHUB_QUERY_MEMINFO)
@@ -277,7 +279,7 @@
 
 int SystemComm::AppMgmtSession::setup(const hub_message_t *appMsg)
 {
-    Mutex::Autolock _l(mLock);
+    std::lock_guard<std::mutex> _l(mLock);
 
     char data[MAX_RX_PACKET];
     MessageBuf buf(data, sizeof(data));
@@ -333,7 +335,7 @@
 int SystemComm::AppMgmtSession::handleRx(MessageBuf &buf)
 {
     int ret = 0;
-    Mutex::Autolock _l(mLock);
+    std::lock_guard<std::mutex> _l(mLock);
     NanohubRsp rsp(buf);
 
     switch (getState()) {
@@ -477,7 +479,7 @@
 }
 
 int SystemComm::KeyInfoSession::setup(const hub_message_t *) {
-    Mutex::Autolock _l(mLock);
+    std::lock_guard<std::mutex> _l(mLock);
     mRsaKeyData.clear();
     setState(SESSION_USER);
     mStatus = -EBUSY;
@@ -486,7 +488,7 @@
 
 int SystemComm::KeyInfoSession::handleRx(MessageBuf &buf)
 {
-    Mutex::Autolock _l(mLock);
+    std::lock_guard<std::mutex> _l(mLock);
     NanohubRsp rsp(buf, true);
 
     if (getState() != SESSION_USER) {
diff --git a/contexthubhal/system_comms.h b/contexthubhal/system_comms.h
index a21aee7..70d6ae1 100644
--- a/contexthubhal/system_comms.h
+++ b/contexthubhal/system_comms.h
@@ -18,9 +18,10 @@
 #define _NANOHUB_SYSTEM_COMMS_H_
 
 #include <utils/Condition.h>
-#include <utils/Mutex.h>
 
+#include <condition_variable>
 #include <map>
+#include <mutex>
 #include <vector>
 
 #include <hardware/context_hub.h>
@@ -118,12 +119,12 @@
     class Session : public ISession {
         friend class SessionManager;
 
-        mutable Mutex mDoneLock; // controls condition and state transitions
-        Condition mDoneWait;
+        mutable std::mutex mDoneMutex; // controls condition and state transitions
+        std::condition_variable mDoneCond;
         volatile int mState;
 
     protected:
-        mutable Mutex mLock; // serializes message handling
+        mutable std::mutex mLock; // serializes message handling
         int32_t mStatus;
 
         enum {
@@ -133,43 +134,42 @@
         };
 
         void complete() {
-            Mutex::Autolock _l(mDoneLock);
+            std::unique_lock<std::mutex> lk(mDoneMutex);
             if (mState != SESSION_DONE) {
                 mState = SESSION_DONE;
-                mDoneWait.broadcast();
+                lk.unlock();
+                mDoneCond.notify_all();
             }
         }
         void setState(int state) {
             if (state == SESSION_DONE) {
                 complete();
             } else {
-                Mutex::Autolock _l(mDoneLock);
+                std::lock_guard<std::mutex> _l(mDoneMutex);
                 mState = state;
             }
         }
     public:
         Session() { mState = SESSION_INIT; mStatus = -1; }
         int getStatus() const {
-            Mutex::Autolock _l(mLock);
+            std::lock_guard<std::mutex> _l(mLock);
             return mStatus;
         }
         int wait() {
-            Mutex::Autolock _l(mDoneLock);
-            while (mState != SESSION_DONE) {
-                mDoneWait.wait(mDoneLock);
-            }
+            std::unique_lock<std::mutex> lk(mDoneMutex);
+            mDoneCond.wait(lk, [this] { return mState == SESSION_DONE; });
             return 0;
         }
         virtual int getState() const override {
-            Mutex::Autolock _l(mDoneLock);
+            std::lock_guard<std::mutex> _l(mDoneMutex);
             return mState;
         }
         virtual bool isDone() const {
-            Mutex::Autolock _l(mDoneLock);
+            std::lock_guard<std::mutex> _l(mDoneMutex);
             return mState == SESSION_DONE;
         }
         virtual bool isRunning() const {
-            Mutex::Autolock _l(mDoneLock);
+            std::lock_guard<std::mutex> _l(mDoneMutex);
             return mState > SESSION_DONE;
         }
     };
@@ -218,7 +218,7 @@
         virtual int setup(const hub_message_t *) override;
         virtual int handleRx(MessageBuf &buf) override;
         bool haveKeys() const {
-            Mutex::Autolock _l(mLock);
+            std::lock_guard<std::mutex> _l(mLock);
             return mRsaKeyData.size() > 0 && !isRunning();
         }
     };
@@ -240,13 +240,13 @@
     class SessionManager {
         typedef std::map<int, Session* > SessionMap;
 
-        Mutex lock;
+        std::mutex lock;
         SessionMap sessions_;
         GlobalSession mGlobal;
 
         void next(SessionMap::iterator &pos)
         {
-            Mutex::Autolock _l(lock);
+            std::lock_guard<std::mutex> _l(lock);
             pos->second->isDone() ? pos = sessions_.erase(pos) : ++pos;
         }
 
@@ -256,7 +256,7 @@
         }
         int handleRx(MessageBuf &buf);
         int setup_and_add(int id, Session *session, const hub_message_t *appMsg) {
-            Mutex::Autolock _l(lock);
+            std::lock_guard<std::mutex> _l(lock);
             if (sessions_.count(id) == 0 && !session->isRunning()) {
                 int ret = session->setup(appMsg);
                 if (ret < 0) {
diff --git a/contexthubhal/test/main.cpp b/contexthubhal/test/main.cpp
index 72245ef..abd2a05 100644
--- a/contexthubhal/test/main.cpp
+++ b/contexthubhal/test/main.cpp
@@ -1,11 +1,16 @@
 #define LOG_TAG "NanohubHAL_Test"
 
+#include <cstddef>
+#include <cstdint>
+#include <functional>
 #include <iostream>
 #include <iomanip>
 #include <map>
 #include <memory>
 #include <cstddef>
 #include <cstdint>
+#include <mutex>
+#include <vector>
 
 #include <unistd.h>
 
@@ -148,9 +153,9 @@
 {
     CHub::Client *mClient;
     std::ostream &log;
-    android::Mutex lock;
+    std::mutex lock;
     void onMessage(const hub_message_t &msg){
-        android::Mutex::Autolock _l(lock);
+        std::lock_guard<std::mutex> _l(lock);
         dumpBuffer(log, "Rx", msg.app_name, msg.message_type, msg.message, msg.message_len, 0);
         log << std::endl;
     }
@@ -169,7 +174,7 @@
         msg.message_type = cmd;
         msg.app_name = mClient->getSystemApp();
         {
-            android::Mutex::Autolock _l(lock);
+            std::lock_guard<std::mutex> _l(lock);
             dumpBuffer(log, "Tx", msg.app_name, msg.message_type, msg.message, msg.message_len, 0);
             log << std::endl;
         }
@@ -212,6 +217,7 @@
             exit(1);
         }
     }
+    // send HAL command
     switch(cmd) {
     case CONTEXT_HUB_APPS_ENABLE:
     {
@@ -234,7 +240,7 @@
             req = (load_app_request_t *)loadFile(appFileName, &fileSize);
         if (!req || fileSize < sizeof(*req) || req->app_binary.magic != NANOAPP_MAGIC) {
             std::clog << "Invalid nanoapp image: " << appFileName << std::endl;
-            exit(1);
+            return 1;
         }
         cli.sendMessageToSystem(CONTEXT_HUB_LOAD_APP, req, fileSize);
         free(req);