unique HosstConnection

Change-Id: I37425906eeecfc9a8a2c3a693efa248683ce3308
diff --git a/system/OpenglSystemCommon/HostConnection.cpp b/system/OpenglSystemCommon/HostConnection.cpp
index 28305d3..4792eec 100644
--- a/system/OpenglSystemCommon/HostConnection.cpp
+++ b/system/OpenglSystemCommon/HostConnection.cpp
@@ -100,6 +100,84 @@
     delete m_rcEnc;
 }
 
+// static
+HostConnection* HostConnection::connect(HostConnection* con) {
+    if (!con) return con;
+
+    const enum HostConnectionType connType = HOST_CONNECTION_VIRTIO_GPU;
+
+    switch (connType) {
+        default:
+        case HOST_CONNECTION_QEMU_PIPE: {
+            QemuPipeStream *stream = new QemuPipeStream(STREAM_BUFFER_SIZE);
+            if (!stream) {
+                ALOGE("Failed to create QemuPipeStream for host connection!!!\n");
+                delete con;
+                return NULL;
+            }
+            if (stream->connect() < 0) {
+                ALOGE("Failed to connect to host (QemuPipeStream)!!!\n");
+                delete stream;
+                delete con;
+                return NULL;
+            }
+            con->m_stream = stream;
+            con->m_grallocHelper = &m_goldfishGralloc;
+            con->m_processPipe = &m_goldfishProcessPipe;
+            break;
+        }
+        case HOST_CONNECTION_TCP: {
+            TcpStream *stream = new TcpStream(STREAM_BUFFER_SIZE);
+            if (!stream) {
+                ALOGE("Failed to create TcpStream for host connection!!!\n");
+                delete con;
+                return NULL;
+            }
+
+            if (stream->connect("10.0.2.2", STREAM_PORT_NUM) < 0) {
+                ALOGE("Failed to connect to host (TcpStream)!!!\n");
+                delete stream;
+                delete con;
+                return NULL;
+            }
+            con->m_stream = stream;
+            con->m_grallocHelper = &m_goldfishGralloc;
+            con->m_processPipe = &m_goldfishProcessPipe;
+            break;
+        }
+#ifdef VIRTIO_GPU
+        case HOST_CONNECTION_VIRTIO_GPU: {
+            VirtioGpuStream *stream = new VirtioGpuStream(STREAM_BUFFER_SIZE);
+            if (!stream) {
+                ALOGE("Failed to create VirtioGpu for host connection!!!\n");
+                delete con;
+                return NULL;
+            }
+            if (stream->connect() < 0) {
+                ALOGE("Failed to connect to host (VirtioGpu)!!!\n");
+                delete stream;
+                delete con;
+                return NULL;
+            }
+            con->m_stream = stream;
+            con->m_grallocHelper = stream->getGralloc();
+            con->m_processPipe = stream->getProcessPipe();
+            break;
+        }
+#endif
+    }
+
+    // send zero 'clientFlags' to the host.
+    unsigned int *pClientFlags =
+            (unsigned int *)con->m_stream->allocBuffer(sizeof(unsigned int));
+    *pClientFlags = 0;
+    con->m_stream->commitBuffer(sizeof(unsigned int));
+
+    ALOGD("HostConnection::get() New Host Connection established %p, tid %d\n",
+          con, getCurrentThreadId());
+    return con;
+}
+
 HostConnection *HostConnection::get() {
     return getWithThreadInfo(getEGLThreadInfo());
 }
@@ -116,79 +194,8 @@
 
     if (tinfo->hostConn == NULL) {
         HostConnection *con = new HostConnection();
-        if (NULL == con) {
-            return NULL;
-        }
+        con = connect(con);
 
-        switch (connType) {
-            default:
-            case HOST_CONNECTION_QEMU_PIPE: {
-                QemuPipeStream *stream = new QemuPipeStream(STREAM_BUFFER_SIZE);
-                if (!stream) {
-                    ALOGE("Failed to create QemuPipeStream for host connection!!!\n");
-                    delete con;
-                    return NULL;
-                }
-                if (stream->connect() < 0) {
-                    ALOGE("Failed to connect to host (QemuPipeStream)!!!\n");
-                    delete stream;
-                    delete con;
-                    return NULL;
-                }
-                con->m_stream = stream;
-                con->m_grallocHelper = &m_goldfishGralloc;
-                con->m_processPipe = &m_goldfishProcessPipe;
-                break;
-            }
-            case HOST_CONNECTION_TCP: {
-                TcpStream *stream = new TcpStream(STREAM_BUFFER_SIZE);
-                if (!stream) {
-                    ALOGE("Failed to create TcpStream for host connection!!!\n");
-                    delete con;
-                    return NULL;
-                }
-
-                if (stream->connect("10.0.2.2", STREAM_PORT_NUM) < 0) {
-                    ALOGE("Failed to connect to host (TcpStream)!!!\n");
-                    delete stream;
-                    delete con;
-                    return NULL;
-                }
-                con->m_stream = stream;
-                con->m_grallocHelper = &m_goldfishGralloc;
-                con->m_processPipe = &m_goldfishProcessPipe;
-                break;
-            }
-#ifdef VIRTIO_GPU
-            case HOST_CONNECTION_VIRTIO_GPU: {
-                VirtioGpuStream *stream = new VirtioGpuStream(STREAM_BUFFER_SIZE);
-                if (!stream) {
-                    ALOGE("Failed to create VirtioGpu for host connection!!!\n");
-                    delete con;
-                    return NULL;
-                }
-                if (stream->connect() < 0) {
-                    ALOGE("Failed to connect to host (VirtioGpu)!!!\n");
-                    delete stream;
-                    delete con;
-                    return NULL;
-                }
-                con->m_stream = stream;
-                con->m_grallocHelper = stream->getGralloc();
-                con->m_processPipe = stream->getProcessPipe();
-                break;
-            }
-#endif
-        }
-
-        // send zero 'clientFlags' to the host.
-        unsigned int *pClientFlags =
-                (unsigned int *)con->m_stream->allocBuffer(sizeof(unsigned int));
-        *pClientFlags = 0;
-        con->m_stream->commitBuffer(sizeof(unsigned int));
-
-        ALOGD("HostConnection::get() New Host Connection established %p, tid %d\n",
-              con, getCurrentThreadId());
         tinfo->hostConn = con;
     }
 
@@ -207,7 +214,16 @@
     }
 }
 
+// static 
+HostConnection *HostConnection::createUnique() {
+    ALOGD("%s: call\n", __func__);
+    return connect(new HostConnection());
+}
 
+// static
+void HostConnection::teardownUnique(HostConnection* con) {
+    delete con;
+}
 
 GLEncoder *HostConnection::glEncoder()
 {
diff --git a/system/OpenglSystemCommon/HostConnection.h b/system/OpenglSystemCommon/HostConnection.h
index 2a4037f..d6a7940 100644
--- a/system/OpenglSystemCommon/HostConnection.h
+++ b/system/OpenglSystemCommon/HostConnection.h
@@ -23,6 +23,8 @@
 #include "goldfish_dma.h"
 
 #include <cutils/native_handle.h>
+#include <utils/threads.h>
+
 #include <string>
 
 class GLEncoder;
@@ -97,6 +99,10 @@
     static HostConnection *get();
     static HostConnection *getWithThreadInfo(EGLThreadInfo* tInfo);
     static void exit();
+
+    static HostConnection *createUnique();
+    static void teardownUnique(HostConnection* con);
+
     ~HostConnection();
 
     GLEncoder *glEncoder();
@@ -118,7 +124,14 @@
 
     bool isGrallocOnly() const { return m_grallocOnly; }
 
+    void lock() const { m_lock.lock(); }
+    void unlock() const { m_lock.unlock(); }
+
 private:
+    // If the connection failed, |conn| is deleted.
+    // Returns NULL if connection failed.
+    static HostConnection* connect(HostConnection* con);
+
     HostConnection();
     static gl_client_context_t  *s_getGLContext();
     static gl2_client_context_t *s_getGL2Context();
@@ -147,6 +160,7 @@
     std::string m_glExtensions;
     bool m_grallocOnly;
     bool m_noHostError;
+    mutable android::Mutex m_lock;
 };
 
 #endif