aboutsummaryrefslogtreecommitdiffstats
path: root/emulator
diff options
context:
space:
mode:
authorDavid 'Digit' Turner <digit@google.com>2014-07-21 16:22:38 +0000
committerandroid-build-merger <android-build-merger@google.com>2014-07-21 16:22:38 +0000
commitc245592b0d472437ade15a22076c2193441f0eea (patch)
tree889f16f76567054ea5fc085f274ceade0a09bd81 /emulator
parent245fae139423eb268ecb3eaa06f6ce8c7044c4f4 (diff)
parent4e4233679d4ef4e25d13fe3b56bd8cdaa3b822cc (diff)
downloadsdk-c245592b0d472437ade15a22076c2193441f0eea.zip
sdk-c245592b0d472437ade15a22076c2193441f0eea.tar.gz
sdk-c245592b0d472437ade15a22076c2193441f0eea.tar.bz2
Merge changes I551e0f3d,I26d84cf5,I27c993d1 into idea133
automerge: 4e42336 * commit '4e4233679d4ef4e25d13fe3b56bd8cdaa3b822cc': emulator/opengl: Remove out-of-process handling code. emulator/opengl: refactor Thread class. emulator/opengl: refactor shared library handling.
Diffstat (limited to 'emulator')
-rw-r--r--emulator/opengl/Android.mk1
-rw-r--r--emulator/opengl/host/libs/GLESv1_dec/Android.mk4
-rw-r--r--emulator/opengl/host/libs/GLESv1_dec/GLDecoder.cpp2
-rw-r--r--emulator/opengl/host/libs/GLESv1_dec/GLDecoder.h4
-rw-r--r--emulator/opengl/host/libs/GLESv2_dec/Android.mk4
-rw-r--r--emulator/opengl/host/libs/GLESv2_dec/GL2Decoder.cpp2
-rw-r--r--emulator/opengl/host/libs/GLESv2_dec/GL2Decoder.h5
-rw-r--r--emulator/opengl/host/libs/Translator/EGL/EglImp.cpp4
-rw-r--r--emulator/opengl/host/libs/Translator/GLcommon/Android.mk2
-rw-r--r--emulator/opengl/host/libs/Translator/GLcommon/GLDispatch.cpp8
-rw-r--r--emulator/opengl/host/libs/libOpenglRender/Android.mk6
-rw-r--r--emulator/opengl/host/libs/libOpenglRender/EGLDispatch.cpp5
-rw-r--r--emulator/opengl/host/libs/libOpenglRender/GL2Dispatch.cpp7
-rw-r--r--emulator/opengl/host/libs/libOpenglRender/GLDispatch.cpp7
-rw-r--r--emulator/opengl/host/libs/libOpenglRender/RenderServer.cpp5
-rw-r--r--emulator/opengl/host/libs/libOpenglRender/RenderServer.h6
-rw-r--r--emulator/opengl/host/libs/libOpenglRender/RenderThread.cpp4
-rw-r--r--emulator/opengl/host/libs/libOpenglRender/RenderThread.h6
-rw-r--r--emulator/opengl/host/libs/libOpenglRender/render_api.cpp127
-rw-r--r--emulator/opengl/host/renderer/Android.mk6
-rw-r--r--emulator/opengl/host/renderer/main.cpp2
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/Android.mk7
-rw-r--r--emulator/opengl/shared/OpenglOsUtils/Android.mk48
-rw-r--r--emulator/opengl/shared/OpenglOsUtils/osDynLibrary.cpp79
-rw-r--r--emulator/opengl/shared/OpenglOsUtils/osDynLibrary.h71
-rw-r--r--emulator/opengl/shared/OpenglOsUtils/osProcess.h62
-rw-r--r--emulator/opengl/shared/OpenglOsUtils/osProcessUnix.cpp210
-rw-r--r--emulator/opengl/shared/OpenglOsUtils/osProcessWin.cpp171
-rw-r--r--emulator/opengl/shared/OpenglOsUtils/osThread.h60
-rw-r--r--emulator/opengl/shared/OpenglOsUtils/osThreadUnix.cpp98
-rw-r--r--emulator/opengl/shared/OpenglOsUtils/osThreadWin.cpp104
-rw-r--r--emulator/opengl/shared/emugl/common/Android.mk26
-rw-r--r--emulator/opengl/shared/emugl/common/shared_library.cpp105
-rw-r--r--emulator/opengl/shared/emugl/common/shared_library.h85
-rw-r--r--emulator/opengl/shared/emugl/common/shared_library_unittest.cpp141
-rw-r--r--emulator/opengl/shared/emugl/common/testing/test_shared_library.cpp22
-rw-r--r--emulator/opengl/shared/emugl/common/thread.h102
-rw-r--r--emulator/opengl/shared/emugl/common/thread_pthread.cpp114
-rw-r--r--emulator/opengl/shared/emugl/common/thread_unittest.cpp109
-rw-r--r--emulator/opengl/shared/emugl/common/thread_win32.cpp122
40 files changed, 876 insertions, 1077 deletions
diff --git a/emulator/opengl/Android.mk b/emulator/opengl/Android.mk
index 856826a..7906fdd 100644
--- a/emulator/opengl/Android.mk
+++ b/emulator/opengl/Android.mk
@@ -73,7 +73,6 @@ include $(EMUGL_PATH)/host/tools/emugen/Android.mk
include $(EMUGL_PATH)/googletest.mk
include $(EMUGL_PATH)/shared/emugl/common/Android.mk
-include $(EMUGL_PATH)/shared/OpenglOsUtils/Android.mk
include $(EMUGL_PATH)/shared/OpenglCodecCommon/Android.mk
# Host static libraries
diff --git a/emulator/opengl/host/libs/GLESv1_dec/Android.mk b/emulator/opengl/host/libs/GLESv1_dec/Android.mk
index 7ab3f0a..e0eca6e 100644
--- a/emulator/opengl/host/libs/GLESv1_dec/Android.mk
+++ b/emulator/opengl/host/libs/GLESv1_dec/Android.mk
@@ -10,7 +10,7 @@ host_common_debug_CFLAGS :=
### host library #########################################
$(call emugl-begin-host-static-library,libGLESv1_dec)
-$(call emugl-import, libOpenglCodecCommon libOpenglOsUtils)
+$(call emugl-import, libOpenglCodecCommon)
$(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
$(call emugl-gen-decoder,$(LOCAL_PATH),gl)
@@ -27,7 +27,7 @@ $(call emugl-end-module)
ifdef EMUGL_BUILD_64BITS
$(call emugl-begin-host64-static-library,lib64GLESv1_dec)
- $(call emugl-import, lib64OpenglCodecCommon lib64OpenglOsUtils)
+ $(call emugl-import, lib64OpenglCodecCommon)
$(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
$(call emugl-gen-decoder,$(LOCAL_PATH),gl)
diff --git a/emulator/opengl/host/libs/GLESv1_dec/GLDecoder.cpp b/emulator/opengl/host/libs/GLESv1_dec/GLDecoder.cpp
index 3c5bd70..7aa6ede 100644
--- a/emulator/opengl/host/libs/GLESv1_dec/GLDecoder.cpp
+++ b/emulator/opengl/host/libs/GLESv1_dec/GLDecoder.cpp
@@ -47,7 +47,7 @@ int GLDecoder::initGL(get_proc_func_t getProcFunc, void *getProcFuncData)
libname = getenv(GLES_LIBNAME_VAR);
}
- m_glesDso = osUtils::dynLibrary::open(libname);
+ m_glesDso = emugl::SharedLibrary::open(libname);
if (m_glesDso == NULL) {
fprintf(stderr, "Couldn't find %s \n", GLES_LIBNAME);
return -1;
diff --git a/emulator/opengl/host/libs/GLESv1_dec/GLDecoder.h b/emulator/opengl/host/libs/GLESv1_dec/GLDecoder.h
index 14ca222..0d26090 100644
--- a/emulator/opengl/host/libs/GLESv1_dec/GLDecoder.h
+++ b/emulator/opengl/host/libs/GLESv1_dec/GLDecoder.h
@@ -19,7 +19,7 @@
#include "gl_dec.h"
#include "FixedBuffer.h"
#include "GLDecoderContextData.h"
-#include <osDynLibrary.h>
+#include "emugl/common/shared_library.h"
#define GLES_LIBNAME_VAR "ANDROID_GLESv1_LIB"
#define GLES_LIBNAME "libGLES_CM.so"
@@ -65,7 +65,7 @@ private:
static void * s_getProc(const char *name, void *userData);
GLDecoderContextData *m_contextData;
- osUtils::dynLibrary* m_glesDso;
+ emugl::SharedLibrary* m_glesDso;
};
#endif
diff --git a/emulator/opengl/host/libs/GLESv2_dec/Android.mk b/emulator/opengl/host/libs/GLESv2_dec/Android.mk
index bc04c25..f658f11 100644
--- a/emulator/opengl/host/libs/GLESv2_dec/Android.mk
+++ b/emulator/opengl/host/libs/GLESv2_dec/Android.mk
@@ -9,7 +9,7 @@ host_common_debug_CFLAGS :=
### host library ##########################################
$(call emugl-begin-host-static-library,libGLESv2_dec)
-$(call emugl-import, libOpenglCodecCommon libOpenglOsUtils)
+$(call emugl-import, libOpenglCodecCommon)
$(call emugl-gen-decoder,$(LOCAL_PATH),gl2)
# For gl2_types.h !
@@ -24,7 +24,7 @@ $(call emugl-end-module)
### host library, 64-bit ####################################
ifdef EMUGL_BUILD_64BITS
$(call emugl-begin-host64-static-library,lib64GLESv2_dec)
- $(call emugl-import, lib64OpenglCodecCommon lib64OpenglOsUtils)
+ $(call emugl-import, lib64OpenglCodecCommon)
$(call emugl-gen-decoder,$(LOCAL_PATH),gl2)
# For gl2_types.h !
diff --git a/emulator/opengl/host/libs/GLESv2_dec/GL2Decoder.cpp b/emulator/opengl/host/libs/GLESv2_dec/GL2Decoder.cpp
index ccf2f06..2ef306e 100644
--- a/emulator/opengl/host/libs/GLESv2_dec/GL2Decoder.cpp
+++ b/emulator/opengl/host/libs/GLESv2_dec/GL2Decoder.cpp
@@ -60,7 +60,7 @@ int GL2Decoder::initGL(get_proc_func_t getProcFunc, void *getProcFuncData)
libname = getenv(GLES2_LIBNAME_VAR);
}
- m_GL2library = osUtils::dynLibrary::open(libname);
+ m_GL2library = emugl::SharedLibrary::open(libname);
if (m_GL2library == NULL) {
fprintf(stderr, "%s: Couldn't find %s \n", __FUNCTION__, libname);
return -1;
diff --git a/emulator/opengl/host/libs/GLESv2_dec/GL2Decoder.h b/emulator/opengl/host/libs/GLESv2_dec/GL2Decoder.h
index dcf2c07..8910da9 100644
--- a/emulator/opengl/host/libs/GLESv2_dec/GL2Decoder.h
+++ b/emulator/opengl/host/libs/GLESv2_dec/GL2Decoder.h
@@ -21,9 +21,8 @@
#define GLES2_LIBNAME "libGLESv2.so"
#include "gl2_dec.h"
-#include "osDynLibrary.h"
#include "GLDecoderContextData.h"
-
+#include "emugl/common/shared_library.h"
class GL2Decoder : public gl2_decoder_context_t
{
@@ -35,7 +34,7 @@ public:
void setContextData(GLDecoderContextData *contextData) { m_contextData = contextData; }
private:
GLDecoderContextData *m_contextData;
- osUtils::dynLibrary * m_GL2library;
+ emugl::SharedLibrary* m_GL2library;
static void *s_getProc(const char *name, void *userData);
static void gl2_APIENTRY s_glGetCompressedTextureFormats(void *self, int count, GLint *formats);
diff --git a/emulator/opengl/host/libs/Translator/EGL/EglImp.cpp b/emulator/opengl/host/libs/Translator/EGL/EglImp.cpp
index 06dcf67..30d358f 100644
--- a/emulator/opengl/host/libs/Translator/EGL/EglImp.cpp
+++ b/emulator/opengl/host/libs/Translator/EGL/EglImp.cpp
@@ -24,7 +24,7 @@
#include <stdio.h>
#include "ThreadInfo.h"
#include <GLcommon/TranslatorIfaces.h>
-#include <OpenglOsUtils/osDynLibrary.h>
+#include "emugl/common/shared_library.h"
#include "EglWindowSurface.h"
#include "EglPbufferSurface.h"
@@ -175,7 +175,7 @@ EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id) {
#define TRANSLATOR_GETIFACE_NAME "__translator_getIfaces"
static __translator_getGLESIfaceFunc loadIfaces(const char* libName){
- osUtils::dynLibrary* libGLES = osUtils::dynLibrary::open(libName);
+ emugl::SharedLibrary* libGLES = emugl::SharedLibrary::open(libName);
if(!libGLES) return NULL;
__translator_getGLESIfaceFunc func = (__translator_getGLESIfaceFunc)libGLES->findSymbol(TRANSLATOR_GETIFACE_NAME);
diff --git a/emulator/opengl/host/libs/Translator/GLcommon/Android.mk b/emulator/opengl/host/libs/Translator/GLcommon/Android.mk
index b215329..fdbedad 100644
--- a/emulator/opengl/host/libs/Translator/GLcommon/Android.mk
+++ b/emulator/opengl/host/libs/Translator/GLcommon/Android.mk
@@ -35,7 +35,6 @@ endif
$(call emugl-begin-host-static-library,libGLcommon)
-$(call emugl-import,libOpenglOsUtils)
translator_path := $(LOCAL_PATH)/..
LOCAL_SRC_FILES := $(host_common_SRC_FILES)
$(call emugl-export,LDLIBS,$(host_common_LDLIBS))
@@ -50,7 +49,6 @@ $(call emugl-end-module)
ifdef EMUGL_BUILD_64BITS
$(call emugl-begin-host64-static-library,lib64GLcommon)
- $(call emugl-import,lib64OpenglOsUtils)
translator_path := $(LOCAL_PATH)/..
LOCAL_SRC_FILES := $(host_common_SRC_FILES)
LOCAL_CFLAGS += -fPIC
diff --git a/emulator/opengl/host/libs/Translator/GLcommon/GLDispatch.cpp b/emulator/opengl/host/libs/Translator/GLcommon/GLDispatch.cpp
index 7b217fd..5da7247 100644
--- a/emulator/opengl/host/libs/Translator/GLcommon/GLDispatch.cpp
+++ b/emulator/opengl/host/libs/Translator/GLcommon/GLDispatch.cpp
@@ -16,7 +16,7 @@
#include <GLcommon/GLDispatch.h>
#include <stdio.h>
-#include <OpenglOsUtils/osDynLibrary.h>
+#include "emugl/common/shared_library.h"
#ifdef __linux__
#include <GL/glx.h>
@@ -31,13 +31,13 @@ typedef void (*GL_FUNC_PTR)();
static GL_FUNC_PTR getGLFuncAddress(const char *funcName) {
GL_FUNC_PTR ret = NULL;
#ifdef __linux__
- static osUtils::dynLibrary* libGL = osUtils::dynLibrary::open("libGL.so");
+ static emugl::SharedLibrary* libGL = emugl::SharedLibrary::open("libGL");
ret = (GL_FUNC_PTR)glXGetProcAddress((const GLubyte*)funcName);
#elif defined(WIN32)
- static osUtils::dynLibrary* libGL = osUtils::dynLibrary::open("opengl32");
+ static emugl::SharedLibrary* libGL = emugl::SharedLibrary::open("opengl32");
ret = (GL_FUNC_PTR)wglGetProcAddress(funcName);
#elif defined(__APPLE__)
- static osUtils::dynLibrary* libGL = osUtils::dynLibrary::open("/System/Library/Frameworks/OpenGL.framework/OpenGL");
+ static emugl::SharedLibrary* libGL = emugl::SharedLibrary::open("/System/Library/Frameworks/OpenGL.framework/OpenGL");
#endif
if(!ret && libGL){
ret = libGL->findSymbol(funcName);
diff --git a/emulator/opengl/host/libs/libOpenglRender/Android.mk b/emulator/opengl/host/libs/libOpenglRender/Android.mk
index 787ae83..ca5a08a 100644
--- a/emulator/opengl/host/libs/libOpenglRender/Android.mk
+++ b/emulator/opengl/host/libs/libOpenglRender/Android.mk
@@ -5,7 +5,7 @@ host_common_LDLIBS :=
ifeq ($(HOST_OS),linux)
host_OS_SRCS = NativeLinuxSubWindow.cpp
- host_common_LDLIBS += -lX11
+ host_common_LDLIBS += -lX11 -lrt
endif
ifeq ($(HOST_OS),darwin)
@@ -43,7 +43,7 @@ host_common_CFLAGS :=
### host libOpenglRender #################################################
$(call emugl-begin-host-shared-library,libOpenglRender)
-$(call emugl-import,libGLESv1_dec libGLESv2_dec lib_renderControl_dec libOpenglCodecCommon libOpenglOsUtils)
+$(call emugl-import,libGLESv1_dec libGLESv2_dec lib_renderControl_dec libOpenglCodecCommon)
LOCAL_LDLIBS += $(host_common_LDLIBS)
@@ -65,7 +65,7 @@ $(call emugl-end-module)
ifdef EMUGL_BUILD_64BITS
$(call emugl-begin-host64-shared-library,lib64OpenglRender)
- $(call emugl-import,lib64GLESv1_dec lib64GLESv2_dec lib64_renderControl_dec lib64OpenglCodecCommon lib64OpenglOsUtils)
+ $(call emugl-import,lib64GLESv1_dec lib64GLESv2_dec lib64_renderControl_dec lib64OpenglCodecCommon)
#LOCAL_LDFLAGS += -m64 # adding -m64 here doesn't work, because it somehow appear BEFORE -m32 in command-line.
LOCAL_LDLIBS += $(host_common_LDLIBS) -m64 # Put -m64 it in LOCAL_LDLIBS instead.
diff --git a/emulator/opengl/host/libs/libOpenglRender/EGLDispatch.cpp b/emulator/opengl/host/libs/libOpenglRender/EGLDispatch.cpp
index 3cf5dbc..7d514e8 100644
--- a/emulator/opengl/host/libs/libOpenglRender/EGLDispatch.cpp
+++ b/emulator/opengl/host/libs/libOpenglRender/EGLDispatch.cpp
@@ -16,7 +16,8 @@
#include "EGLDispatch.h"
#include <stdio.h>
#include <stdlib.h>
-#include "osDynLibrary.h"
+
+#include "emugl/common/shared_library.h"
EGLDispatch s_egl;
@@ -28,7 +29,7 @@ bool init_egl_dispatch()
const char *libName = getenv("ANDROID_EGL_LIB");
if (!libName) libName = DEFAULT_EGL_LIB;
- osUtils::dynLibrary *lib = osUtils::dynLibrary::open(libName);
+ emugl::SharedLibrary *lib = emugl::SharedLibrary::open(libName);
if (!lib) {
printf("Failed to open %s\n", libName);
return NULL;
diff --git a/emulator/opengl/host/libs/libOpenglRender/GL2Dispatch.cpp b/emulator/opengl/host/libs/libOpenglRender/GL2Dispatch.cpp
index cda205f..8c51a4e 100644
--- a/emulator/opengl/host/libs/libOpenglRender/GL2Dispatch.cpp
+++ b/emulator/opengl/host/libs/libOpenglRender/GL2Dispatch.cpp
@@ -17,12 +17,13 @@
#include "GL2Dispatch.h"
#include <stdio.h>
#include <stdlib.h>
-#include "osDynLibrary.h"
+
+#include "emugl/common/shared_library.h"
gl2_decoder_context_t s_gl2;
int s_gl2_enabled;
-static osUtils::dynLibrary *s_gles2_lib = NULL;
+static emugl::SharedLibrary *s_gles2_lib = NULL;
#define DEFAULT_GLES_V2_LIB EMUGL_LIBNAME("GLES_V2_translator")
@@ -38,7 +39,7 @@ bool init_gl2_dispatch()
//
// Load the GLES library
//
- s_gles2_lib = osUtils::dynLibrary::open(libName);
+ s_gles2_lib = emugl::SharedLibrary::open(libName);
if (!s_gles2_lib) return false;
//
diff --git a/emulator/opengl/host/libs/libOpenglRender/GLDispatch.cpp b/emulator/opengl/host/libs/libOpenglRender/GLDispatch.cpp
index 089512a..c127dc3 100644
--- a/emulator/opengl/host/libs/libOpenglRender/GLDispatch.cpp
+++ b/emulator/opengl/host/libs/libOpenglRender/GLDispatch.cpp
@@ -16,11 +16,12 @@
#include "GLDispatch.h"
#include <stdio.h>
#include <stdlib.h>
-#include "osDynLibrary.h"
+
+#include "emugl/common/shared_library.h"
GLDispatch s_gl;
-static osUtils::dynLibrary *s_gles_lib = NULL;
+static emugl::SharedLibrary *s_gles_lib = NULL;
//
// This function is called only once during initialiation before
@@ -34,7 +35,7 @@ bool init_gl_dispatch()
const char *libName = getenv("ANDROID_GLESv1_LIB");
if (!libName) libName = DEFAULT_GLES_CM_LIB;
- s_gles_lib = osUtils::dynLibrary::open(libName);
+ s_gles_lib = emugl::SharedLibrary::open(libName);
if (!s_gles_lib) return false;
s_gl.glAlphaFunc = (glAlphaFunc_t) s_gles_lib->findSymbol("glAlphaFunc");
diff --git a/emulator/opengl/host/libs/libOpenglRender/RenderServer.cpp b/emulator/opengl/host/libs/libOpenglRender/RenderServer.cpp
index de28f8f..53c65ee 100644
--- a/emulator/opengl/host/libs/libOpenglRender/RenderServer.cpp
+++ b/emulator/opengl/host/libs/libOpenglRender/RenderServer.cpp
@@ -77,7 +77,7 @@ RenderServer *RenderServer::create(char* addr, size_t addrLen)
return server;
}
-int RenderServer::Main()
+intptr_t RenderServer::main()
{
RenderThreadsSet threads;
@@ -146,8 +146,7 @@ int RenderServer::Main()
for (RenderThreadsSet::iterator t = threads.begin();
t != threads.end();
t++) {
- int exitStatus;
- (*t)->wait(&exitStatus);
+ (*t)->wait(NULL);
delete (*t);
}
threads.clear();
diff --git a/emulator/opengl/host/libs/libOpenglRender/RenderServer.h b/emulator/opengl/host/libs/libOpenglRender/RenderServer.h
index ff63c94..8be8a17 100644
--- a/emulator/opengl/host/libs/libOpenglRender/RenderServer.h
+++ b/emulator/opengl/host/libs/libOpenglRender/RenderServer.h
@@ -18,15 +18,15 @@
#include "SocketStream.h"
#include "emugl/common/mutex.h"
-#include "osThread.h"
+#include "emugl/common/thread.h"
-class RenderServer : public osUtils::Thread
+class RenderServer : public emugl::Thread
{
public:
static RenderServer *create(char* addr, size_t addrLen);
virtual ~RenderServer();
- virtual int Main();
+ virtual intptr_t main();
bool isExiting() const { return m_exiting; }
diff --git a/emulator/opengl/host/libs/libOpenglRender/RenderThread.cpp b/emulator/opengl/host/libs/libOpenglRender/RenderThread.cpp
index 19d6c1f..3dcfdb5 100644
--- a/emulator/opengl/host/libs/libOpenglRender/RenderThread.cpp
+++ b/emulator/opengl/host/libs/libOpenglRender/RenderThread.cpp
@@ -26,7 +26,7 @@
#define STREAM_BUFFER_SIZE 4*1024*1024
RenderThread::RenderThread(IOStream *stream, emugl::Mutex *lock) :
- osUtils::Thread(),
+ emugl::Thread(),
m_lock(lock),
m_stream(stream),
m_finished(false)
@@ -43,7 +43,7 @@ RenderThread *RenderThread::create(IOStream *p_stream, emugl::Mutex *lock)
return new RenderThread(p_stream, lock);
}
-int RenderThread::Main()
+intptr_t RenderThread::main()
{
RenderThreadInfo tInfo;
diff --git a/emulator/opengl/host/libs/libOpenglRender/RenderThread.h b/emulator/opengl/host/libs/libOpenglRender/RenderThread.h
index e94d782..c1f919a 100644
--- a/emulator/opengl/host/libs/libOpenglRender/RenderThread.h
+++ b/emulator/opengl/host/libs/libOpenglRender/RenderThread.h
@@ -21,9 +21,9 @@
#include "renderControl_dec.h"
#include "emugl/common/mutex.h"
-#include "osThread.h"
+#include "emugl/common/thread.h"
-class RenderThread : public osUtils::Thread
+class RenderThread : public emugl::Thread
{
public:
static RenderThread* create(IOStream* p_stream, emugl::Mutex* mutex);
@@ -32,7 +32,7 @@ public:
private:
RenderThread(IOStream* p_stream, emugl::Mutex* mutex);
- virtual int Main();
+ virtual intptr_t main();
private:
emugl::Mutex *m_lock;
diff --git a/emulator/opengl/host/libs/libOpenglRender/render_api.cpp b/emulator/opengl/host/libs/libOpenglRender/render_api.cpp
index 5c9ffb1..9586091 100644
--- a/emulator/opengl/host/libs/libOpenglRender/render_api.cpp
+++ b/emulator/opengl/host/libs/libOpenglRender/render_api.cpp
@@ -17,7 +17,6 @@
#include "IOStream.h"
#include "FrameBuffer.h"
#include "RenderServer.h"
-#include "osProcess.h"
#include "TimeUtils.h"
#include "TcpStream.h"
@@ -31,25 +30,12 @@
#include "GLDispatch.h"
#include "GL2Dispatch.h"
-static osUtils::childProcess *s_renderProc = NULL;
static RenderServer *s_renderThread = NULL;
static char s_renderAddr[256];
static IOStream *createRenderThread(int p_stream_buffer_size,
unsigned int clientFlags);
-//
-// For now run the renderer as a thread inside the calling
-// process instead as running it in a separate process for all
-// platforms.
-// at the future we want it to run as a seperate process except for
-// Mac OS X since it is imposibble on this platform to make one process
-// render to a window created by another process.
-//
-//#ifdef __APPLE__
-#define RENDER_API_USE_THREAD
-//#endif
-
int initLibrary(void)
{
//
@@ -82,11 +68,10 @@ int initOpenGLRenderer(int width, int height, char* addr, size_t addrLen)
//
// Fail if renderer is already initialized
//
- if (s_renderProc || s_renderThread) {
+ if (s_renderThread) {
return false;
}
-#ifdef RENDER_API_USE_THREAD // should be defined for mac
//
// initialize the renderer and listen to connections
// on a thread in the current process.
@@ -104,110 +89,15 @@ int initOpenGLRenderer(int width, int height, char* addr, size_t addrLen)
s_renderThread->start();
-#else
- if (onPost) {
- // onPost callback not supported with separate renderer process.
- //
- // If we ever revive separate process support, we could make the choice
- // between thread and process at runtime instead of compile time, and
- // choose the thread path if an onPost callback is requested. Or, the
- // callback could be supported with a separate process using shmem or
- // other IPC mechanism.
- return false;
- }
-
- //
- // Launch emulator_renderer
- //
- char cmdLine[128];
- snprintf(cmdLine, 128, "emulator_renderer -windowid %d -port %d -x %d -y %d -width %d -height %d",
- (int)window, portNum, x, y, width, height);
-
- s_renderProc = osUtils::childProcess::create(cmdLine, NULL);
- if (!s_renderProc) {
- return false;
- }
-
- //
- // try to connect to the renderer in order to check it
- // was successfully initialized.
- //
- int nTrys = 0;
- IOStream *dummy = NULL;
- do {
- ++nTrys;
-
- //
- // Wait a bit to make the renderer process a chance to be
- // initialized.
- // On Windows we need during this time to handle windows
- // events since the renderer generates a subwindow of this
- // process's window, we need to be responsive for windows
- // during this time to let the renderer generates this subwindow.
- //
-#ifndef _WIN32
- TimeSleepMS(300);
-#else
- long long t0 = GetCurrentTimeMS();
- while( (GetCurrentTimeMS() - t0) < 300 ) {
- MSG msg;
- int n = 0;
- while( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )
- {
- n++;
- TranslateMessage( &msg );
- DispatchMessage( &msg );
- }
- if (n == 0) TimeSleepMS(10);
- }
-#endif
-
- dummy = createRenderThread(8, 0);
-
- if (!dummy) {
- // stop if the process is no longer running
- if (!osUtils::isProcessRunning(s_renderProc->getPID())) {
- break;
- }
- }
- } while(!dummy && nTrys < 10); // give up after 3 seconds, XXX: ???
-
- if (!dummy) {
- //
- // Failed - make sure the process is killed
- //
- osUtils::KillProcess(s_renderProc->getPID(), true);
- delete s_renderProc;
- s_renderProc = NULL;
- return false;
- }
-
- // destroy the dummy connection
- delete dummy;
-#endif
-
return true;
}
void setPostCallback(OnPostFn onPost, void* onPostContext)
{
-#ifdef RENDER_API_USE_THREAD // should be defined for mac
FrameBuffer* fb = FrameBuffer::getFB();
if (fb) {
fb->setPostCallback(onPost, onPostContext);
}
-#else
- if (onPost) {
- // onPost callback not supported with separate renderer process.
- //
- // If we ever revive separate process support, we could make the choice
- // between thread and process at runtime instead of compile time, and
- // choose the thread path if an onPost callback is requested. Or, the
- // callback could be supported with a separate process using shmem or
- // other IPC mechanism.
- return false;
- }
-#endif
}
void getHardwareStrings(const char** vendor, const char** renderer, const char** version)
@@ -230,21 +120,10 @@ int stopOpenGLRenderer(void)
IOStream *dummy = createRenderThread(8, IOSTREAM_CLIENT_EXIT_SERVER);
if (!dummy) return false;
- if (s_renderProc) {
- //
- // wait for the process to exit
- //
- int exitStatus;
- ret = s_renderProc->wait(&exitStatus);
-
- delete s_renderProc;
- s_renderProc = NULL;
- }
- else if (s_renderThread) {
+ if (s_renderThread) {
// wait for the thread to exit
- int status;
- ret = s_renderThread->wait(&status);
+ ret = s_renderThread->wait(NULL);
delete s_renderThread;
s_renderThread = NULL;
diff --git a/emulator/opengl/host/renderer/Android.mk b/emulator/opengl/host/renderer/Android.mk
index 55fcb80..81dcaf7 100644
--- a/emulator/opengl/host/renderer/Android.mk
+++ b/emulator/opengl/host/renderer/Android.mk
@@ -6,9 +6,9 @@ $(call emugl-import,libOpenglRender)
LOCAL_SRC_FILES := main.cpp
LOCAL_CFLAGS += -O0 -g
-#ifeq ($(HOST_OS),windows)
-#LOCAL_LDLIBS += -lws2_32
-#endif
+ifeq ($(HOST_OS),linux)
+LOCAL_LDLIBS += -lX11
+endif
$(call emugl-end-module)
diff --git a/emulator/opengl/host/renderer/main.cpp b/emulator/opengl/host/renderer/main.cpp
index 2c3f8e2..470e692 100644
--- a/emulator/opengl/host/renderer/main.cpp
+++ b/emulator/opengl/host/renderer/main.cpp
@@ -141,7 +141,7 @@ int main(int argc, char *argv[])
//
// run the server listener loop
//
- server->Main();
+ server->main();
#else
//
// on windows we need to handle messages for the
diff --git a/emulator/opengl/shared/OpenglCodecCommon/Android.mk b/emulator/opengl/shared/OpenglCodecCommon/Android.mk
index 83090d8..0c3f827 100644
--- a/emulator/opengl/shared/OpenglCodecCommon/Android.mk
+++ b/emulator/opengl/shared/OpenglCodecCommon/Android.mk
@@ -13,8 +13,11 @@ commonSources := \
host_commonSources := $(commonSources)
+host_commonLdLibs := -lstdc++
+
ifeq ($(HOST_OS),windows)
host_commonSources += Win32PipeStream.cpp
+ host_commonLdLibs += -lws2_32 -lpsapi
else
host_commonSources += UnixStream.cpp
endif
@@ -26,7 +29,7 @@ $(call emugl-begin-host-static-library,libOpenglCodecCommon)
LOCAL_SRC_FILES := $(host_commonSources)
$(call emugl-import, libemugl_common)
$(call emugl-export,C_INCLUDES,$(EMUGL_PATH)/host/include/libOpenglRender $(LOCAL_PATH))
-$(call emugl-export,LDLIBS,-lstdc++)
+$(call emugl-export,LDLIBS,$(host_commonLdLibs))
$(call emugl-end-module)
@@ -39,6 +42,6 @@ ifdef EMUGL_BUILD_64BITS
$(call emugl-import, lib64emugl_common)
$(call emugl-export,C_INCLUDES,$(EMUGL_PATH)/host/include/libOpenglRender $(LOCAL_PATH))
$(call emugl-export,CFLAGS,-m64 -fPIC)
- $(call emugl-export,LDLIBS,-lstdc++)
+ $(call emugl-export,LDLIBS,$(host_commonLdLibs))
$(call emugl-end-module)
endif
diff --git a/emulator/opengl/shared/OpenglOsUtils/Android.mk b/emulator/opengl/shared/OpenglOsUtils/Android.mk
deleted file mode 100644
index f9673fc..0000000
--- a/emulator/opengl/shared/OpenglOsUtils/Android.mk
+++ /dev/null
@@ -1,48 +0,0 @@
-# This build script corresponds to a small library containing
-# OS-specific support functions for:
-# - thread-local storage
-# - dynamic library loading
-# - child process creation and wait (probably not needed in guest)
-#
-LOCAL_PATH := $(call my-dir)
-
-### Host library ##############################################
-
-host_common_SRC_FILES := osDynLibrary.cpp
-host_common_LDLIBS :=
-host_common_INCLUDES := $(LOCAL_PATH)
-
-ifeq ($(HOST_OS),windows)
- host_common_SRC_FILES += \
- osProcessWin.cpp \
- osThreadWin.cpp
- host_common_LDLIBS += -lws2_32 -lpsapi
-else
- host_common_SRC_FILES += \
- osProcessUnix.cpp \
- osThreadUnix.cpp
- host_common_LDLIBS += -ldl
-endif
-
-ifeq ($(HOST_OS),linux)
- host_common_LDLIBS += -lpthread -lrt -lX11
-endif
-
-### 32-bit host library ####
-$(call emugl-begin-host-static-library,libOpenglOsUtils)
- $(call emugl-export,C_INCLUDES,$(host_common_INCLUDES))
- LOCAL_SRC_FILES = $(host_common_SRC_FILES)
- $(call emugl-export,LDLIBS,$(host_common_LDLIBS))
- $(call emugl-import,libemugl_common)
-$(call emugl-end-module)
-
-### 64-bit host library ####
-ifdef EMUGL_BUILD_64BITS
- $(call emugl-begin-host64-static-library,lib64OpenglOsUtils)
- $(call emugl-export,C_INCLUDES,$(host_common_INCLUDES))
- LOCAL_SRC_FILES = $(host_common_SRC_FILES)
- $(call emugl-export,LDLIBS,$(host_common_LDLIBS))
- $(call emugl-import,lib64emugl_common)
- $(call emugl-export,CFLAGS,-m64 -fPIC)
- $(call emugl-end-module)
-endif
diff --git a/emulator/opengl/shared/OpenglOsUtils/osDynLibrary.cpp b/emulator/opengl/shared/OpenglOsUtils/osDynLibrary.cpp
deleted file mode 100644
index e8e6ab7..0000000
--- a/emulator/opengl/shared/OpenglOsUtils/osDynLibrary.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-#include "osDynLibrary.h"
-
-#ifndef _WIN32
-#include <dlfcn.h>
-#endif
-#include <stdio.h>
-
-namespace osUtils {
-
-dynLibrary *dynLibrary::open(const char *p_libName)
-{
- dynLibrary *lib = new dynLibrary();
- if (!lib) {
- return NULL;
- }
-
-#ifdef _WIN32
- lib->m_lib = LoadLibrary(p_libName);
-#else // !WIN32
- lib->m_lib = dlopen(p_libName, RTLD_NOW);
-#endif
-
- if (lib->m_lib == NULL) {
- printf("Failed to load %s\n", p_libName);
-#ifndef _WIN32
- printf("error %s\n", dlerror()); //only on linux
-#endif
- delete lib;
- return NULL;
- }
-
- return lib;
-}
-
-dynLibrary::dynLibrary() :
- m_lib(NULL)
-{
-}
-
-dynLibrary::~dynLibrary()
-{
- if (NULL != m_lib) {
-#ifdef _WIN32
- FreeLibrary(m_lib);
-#else // !WIN32
- dlclose(m_lib);
-#endif
- }
-}
-
-dynFuncPtr dynLibrary::findSymbol(const char *p_symName)
-{
- if (NULL == m_lib) {
- return NULL;
- }
-
-#ifdef _WIN32
- return (dynFuncPtr) GetProcAddress(m_lib, p_symName);
-#else // !WIN32
- return (dynFuncPtr) dlsym(m_lib, p_symName);
-#endif
-}
-
-} // of namespace osUtils
diff --git a/emulator/opengl/shared/OpenglOsUtils/osDynLibrary.h b/emulator/opengl/shared/OpenglOsUtils/osDynLibrary.h
deleted file mode 100644
index c83fbf3..0000000
--- a/emulator/opengl/shared/OpenglOsUtils/osDynLibrary.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-#ifndef _OSUTILS_DYN_LIBRARY_H
-#define _OSUTILS_DYN_LIBRARY_H
-
-#ifdef _WIN32
-#include <windows.h>
-#endif
-
-namespace osUtils {
-
-typedef void (*dynFuncPtr)(void);
-
-class dynLibrary
-{
-public:
- static dynLibrary *open(const char *p_libName);
- ~dynLibrary();
-
- dynFuncPtr findSymbol(const char *p_symName);
-
-private:
- dynLibrary();
-
-private:
-#ifdef _WIN32
- HMODULE m_lib;
-#else
- void *m_lib;
-#endif
-};
-
-} // of namespace osUtils
-
-
-
-// Macro to compose emugl shared library name under various OS and bitness
-// eg.
-// on x86_64, EMUGL_LIBNAME("foo") --> "lib64foo.so"
-
-#ifdef _WIN32
-# define DLL_EXTENSION "" // _WIN32 LoadLibrary only accept name w/o .dll extension
-#elif defined(__APPLE__)
-# define DLL_EXTENSION ".dylib"
-#else
-# define DLL_EXTENSION ".so"
-#endif
-
-#if defined(__x86_64__)
-# define EMUGL_LIBNAME(name) "lib64" name DLL_EXTENSION
-#elif defined(__i386__)
-# define EMUGL_LIBNAME(name) "lib" name DLL_EXTENSION
-#else
-/* This header is included by target w/o using EMUGL_LIBNAME(). Don't #error, leave it undefined */
-#endif
-
-
-#endif
diff --git a/emulator/opengl/shared/OpenglOsUtils/osProcess.h b/emulator/opengl/shared/OpenglOsUtils/osProcess.h
deleted file mode 100644
index 82b31b3..0000000
--- a/emulator/opengl/shared/OpenglOsUtils/osProcess.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-#ifndef _OSUTILS_PROCESS_H
-#define _OSUTILS_PROCESS_H
-
-#ifdef _WIN32
-#include <windows.h>
-#endif
-
-namespace osUtils {
-
-class childProcess
-{
-public:
- static childProcess *create(const char *p_cmdLine, const char *p_startdir);
- ~childProcess();
-
- int getPID()
- {
-#ifdef _WIN32
- return m_proc.dwProcessId;
-#else
- return(m_pid);
-#endif
- }
-
- int tryWait(bool& isAlive);
- bool wait(int *exitStatus);
-
-private:
- childProcess() {};
-
-private:
-#ifdef _WIN32
- PROCESS_INFORMATION m_proc;
-#else
- int m_pid;
-#endif
-};
-
-int ProcessGetPID();
-int ProcessGetTID();
-bool ProcessGetName(char *p_outName, int p_outNameLen);
-int KillProcess(int pid, bool wait);
-bool isProcessRunning(int pid);
-
-} // of namespace osUtils
-
-#endif
diff --git a/emulator/opengl/shared/OpenglOsUtils/osProcessUnix.cpp b/emulator/opengl/shared/OpenglOsUtils/osProcessUnix.cpp
deleted file mode 100644
index c97ff58..0000000
--- a/emulator/opengl/shared/OpenglOsUtils/osProcessUnix.cpp
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-#include "osProcess.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/wait.h>
-#include <sys/types.h>
-#include <poll.h>
-#include <pthread.h>
-#include <string.h>
-#include <pwd.h>
-#include <paths.h>
-#include <errno.h>
-#include <signal.h>
-#include <unistd.h>
-#include <assert.h>
-
-namespace osUtils {
-
-//
-// buildArgList converts a command line into null terminated argument list.
-// to be used with execv or execvp.
-// each argument is seperated by space or tab, to specify multiple words
-// at the same argument place it inside single-quoted or double-quoted string.
-//
-static char **buildArgList(const char *command)
-{
- char **argv = NULL;
- int argvSize = 0;
- int nArgs = 0;
- char *tmpcmd = strdup(command);
- char *t = tmpcmd;
- char *strStart = NULL;
- int i = 0;
-
- #define ADD_ARG \
- { \
- nArgs++; \
- if (!argv) { \
- argvSize = 12; \
- argv = (char **)malloc(argvSize * sizeof(char *)); \
- } \
- else if (nArgs > argvSize) { \
- argvSize += 12; \
- argv = (char **)realloc(argv, argvSize * sizeof(char *)); \
- } \
- argv[nArgs-1] = t; \
- t = NULL; \
- }
-
- while( tmpcmd[i] != '\0' ) {
- if (!strStart) {
- if (tmpcmd[i] == '"' || tmpcmd[i] == '\'') {
- strStart = &tmpcmd[i];
- }
- else if (tmpcmd[i] == ' ' || tmpcmd[i] == '\t') {
- tmpcmd[i] = '\0';
- if (t) ADD_ARG;
- }
- else if (!t) {
- t = &tmpcmd[i];
- }
- }
- else if (tmpcmd[i] == *strStart) {
- t = strStart;
- strStart = NULL;
- }
-
- i++;
- }
- if (t) {
- ADD_ARG;
- }
- if (nArgs > 0) {
- ADD_ARG; // for NULL terminating list
- }
-
- return argv;
-}
-
-static pid_t start_process(const char *command,const char *startDir)
-{
- pid_t pid;
-
- pid = fork();
-
- if (pid < 0) {
- return pid;
- }
- else if (pid == 0) {
- //
- // Close all opened file descriptors
- //
- for (int i=3; i<256; i++) {
- close(i);
- }
-
- if (startDir) {
- chdir(startDir);
- }
-
- char **argv = buildArgList(command);
- if (!argv) {
- return -1;
- }
- execvp(argv[0], argv);
-
- perror("execl");
- exit(-101);
- }
-
- return pid;
-}
-
-childProcess *
-childProcess::create(const char *p_cmdLine, const char *p_startdir)
-{
- childProcess *child = new childProcess();
- if (!child) {
- return NULL;
- }
-
- child->m_pid = start_process(p_cmdLine, p_startdir);
- if (child->m_pid < 0) {
- delete child;
- return NULL;
- }
-
- return child;
-}
-
-childProcess::~childProcess()
-{
-}
-
-bool
-childProcess::wait(int *exitStatus)
-{
- int ret=0;
- if (m_pid>0) {
- pid_t pid = waitpid(m_pid,&ret,0);
- if (pid != -1) {
- m_pid=-1;
- if (exitStatus) {
- *exitStatus = ret;
- }
- return true;
- }
- }
- return false;
-}
-
-int
-childProcess::tryWait(bool &isAlive)
-{
- int ret=0;
- isAlive = false;
- if (m_pid>0) {
- pid_t pid = waitpid(m_pid,&ret,WNOHANG);
- if (pid == 0) {
- isAlive = true;
- }
- }
-
- return ((char)WEXITSTATUS(ret));
-}
-
-int ProcessGetPID()
-{
- return getpid();
-}
-
-int KillProcess(int pid, bool wait)
-{
- if (pid<1) {
- return false;
- }
-
- if (0!=kill(pid,SIGTERM)) {
- return false;
- }
-
- if (wait) {
- if (waitpid(pid,NULL,0)<0) {
- return false;
- }
- }
-
- return true;
-}
-
-bool isProcessRunning(int pid)
-{
- return (kill(pid,0) == 0);
-}
-
-} // of namespace osUtils
diff --git a/emulator/opengl/shared/OpenglOsUtils/osProcessWin.cpp b/emulator/opengl/shared/OpenglOsUtils/osProcessWin.cpp
deleted file mode 100644
index 6ff0fdf..0000000
--- a/emulator/opengl/shared/OpenglOsUtils/osProcessWin.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-#include "osProcess.h"
-#include <windows.h>
-#include <string>
-#include <stdlib.h>
-#include <psapi.h>
-
-namespace osUtils {
-
-childProcess *
-childProcess::create(const char *p_cmdLine, const char *p_startdir)
-{
- childProcess *child = new childProcess();
- if (!child) {
- return NULL;
- }
-
- STARTUPINFOA si;
- ZeroMemory(&si, sizeof(si));
-
- ZeroMemory(&child->m_proc, sizeof(child->m_proc));
- BOOL ret = CreateProcessA(
- NULL ,
- (LPSTR)p_cmdLine,
- NULL,
- NULL,
- FALSE,
- CREATE_DEFAULT_ERROR_MODE,
- NULL,
- (p_startdir != NULL ? p_startdir : ".\\"),
- &si,
- &child->m_proc);
- if (ret == 0) {
- delete child;
- return NULL;
- }
-
- // close the thread handle we do not need it,
- // keep the process handle for wait/trywait operations, will
- // be closed on destruction
- CloseHandle(child->m_proc.hThread);
-
- return child;
-}
-
-childProcess::~childProcess()
-{
- if (m_proc.hProcess) {
- CloseHandle(m_proc.hProcess);
- }
-}
-
-bool
-childProcess::wait(int *exitStatus)
-{
-DWORD _exitStatus;
-
- if (WaitForSingleObject(m_proc.hProcess, INFINITE) == WAIT_FAILED) {
- return false;
- }
-
- if (!GetExitCodeProcess(m_proc.hProcess, &_exitStatus))
- {
- return false;
- }
-
- if (exitStatus) {
- *exitStatus = _exitStatus;
- }
-
- return true;
-}
-
-int
-childProcess::tryWait(bool& isAlive)
-{
- DWORD status = WaitForSingleObject(m_proc.hProcess, 0);
-
- if(status == WAIT_OBJECT_0)
- {
- // process has exited
- isAlive = false;
- GetExitCodeProcess(m_proc.hProcess, &status);
- }
- else if (status == WAIT_TIMEOUT)
- {
- isAlive = true;
- status = 0;
- }
-
- return status;
-
-}
-
-int ProcessGetPID()
-{
- return GetCurrentProcessId();
-}
-
-int ProcessGetTID()
-{
- return GetCurrentThreadId();
-}
-
-bool ProcessGetName(char *p_outName, int p_outNameLen)
-{
- return 0 != GetModuleFileNameEx( GetCurrentProcess(), NULL, p_outName, p_outNameLen);
-}
-
-int KillProcess(int pid, bool wait)
-{
- DWORD exitStatus = 1;
- HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
-
- if (NULL == hProc) {
- return 0;
- }
-
- //
- // Terminate the process
- //
- TerminateProcess(hProc, 0x55);
-
- if (wait) {
- //
- // Wait for it to be terminated
- //
- if(WaitForSingleObject(hProc, INFINITE) == WAIT_FAILED) {
- CloseHandle(hProc);
- return 0;
- }
-
- if (!GetExitCodeProcess(hProc, &exitStatus)) {
- CloseHandle(hProc);
- return 0;
- }
- }
-
- CloseHandle(hProc);
-
- return exitStatus;
-}
-
-bool isProcessRunning(int pid)
-{
- bool isRunning = false;
-
- HANDLE process = OpenProcess(SYNCHRONIZE, FALSE, pid);
- if (NULL != process) {
- DWORD ret = WaitForSingleObject(process, 0);
- CloseHandle(process);
- isRunning = (ret == WAIT_TIMEOUT);
- }
- return isRunning;
-}
-
-} // of namespace osUtils
diff --git a/emulator/opengl/shared/OpenglOsUtils/osThread.h b/emulator/opengl/shared/OpenglOsUtils/osThread.h
deleted file mode 100644
index 970396d..0000000
--- a/emulator/opengl/shared/OpenglOsUtils/osThread.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-#ifndef _OSUTILS_THREAD_H
-#define _OSUTILS_THREAD_H
-
-#ifdef _WIN32
-#include <windows.h>
-#else // !WIN32
-#include <pthread.h>
-#endif
-
-namespace osUtils {
-
-class Thread
-{
-public:
- Thread();
- virtual ~Thread();
-
- virtual int Main() = 0;
-
- bool start();
- bool wait(int *exitStatus);
- bool trywait(int *exitStatus);
-
-private:
-#ifdef _WIN32
- static DWORD WINAPI thread_main(void *p_arg);
-#else // !WIN32
- static void* thread_main(void *p_arg);
-#endif
-
-private:
-#ifdef _WIN32
- HANDLE m_thread;
- DWORD m_threadId;
-#else // !WIN32
- pthread_t m_thread;
- int m_exitStatus;
- pthread_mutex_t m_lock;
-#endif
- bool m_isRunning;
-};
-
-} // of namespace osUtils
-
-#endif
diff --git a/emulator/opengl/shared/OpenglOsUtils/osThreadUnix.cpp b/emulator/opengl/shared/OpenglOsUtils/osThreadUnix.cpp
deleted file mode 100644
index ef2bebc..0000000
--- a/emulator/opengl/shared/OpenglOsUtils/osThreadUnix.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-#include "osThread.h"
-
-#include "emugl/common/thread_store.h"
-
-#include <stdint.h>
-
-namespace osUtils {
-
-Thread::Thread() :
- m_thread((pthread_t)NULL),
- m_exitStatus(0),
- m_isRunning(false)
-{
- pthread_mutex_init(&m_lock, NULL);
-}
-
-Thread::~Thread()
-{
- pthread_mutex_destroy(&m_lock);
-}
-
-bool
-Thread::start()
-{
- pthread_mutex_lock(&m_lock);
- m_isRunning = true;
- int ret = pthread_create(&m_thread, NULL, Thread::thread_main, this);
- if(ret) {
- m_isRunning = false;
- }
- pthread_mutex_unlock(&m_lock);
- return m_isRunning;
-}
-
-bool
-Thread::wait(int *exitStatus)
-{
- if (!m_isRunning) {
- return false;
- }
-
- void *retval;
- if (pthread_join(m_thread,&retval)) {
- return false;
- }
-
- if (exitStatus) {
- *exitStatus = (int)(uintptr_t)retval;
- }
- return true;
-}
-
-bool
-Thread::trywait(int *exitStatus)
-{
- bool ret = false;
-
- pthread_mutex_lock(&m_lock);
- if (!m_isRunning) {
- *exitStatus = m_exitStatus;
- ret = true;
- }
- pthread_mutex_unlock(&m_lock);
- return ret;
-}
-
-void *
-Thread::thread_main(void *p_arg)
-{
- Thread *self = (Thread *)p_arg;
- int ret = self->Main();
-
- pthread_mutex_lock(&self->m_lock);
- self->m_isRunning = false;
- self->m_exitStatus = ret;
- pthread_mutex_unlock(&self->m_lock);
-
- ::emugl::ThreadStore::OnThreadExit();
- return (void*)(uintptr_t)ret;
-}
-
-} // of namespace osUtils
-
diff --git a/emulator/opengl/shared/OpenglOsUtils/osThreadWin.cpp b/emulator/opengl/shared/OpenglOsUtils/osThreadWin.cpp
deleted file mode 100644
index 1a30b97..0000000
--- a/emulator/opengl/shared/OpenglOsUtils/osThreadWin.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-#include "osThread.h"
-
-#include "emugl/common/thread_store.h"
-
-namespace osUtils {
-
-Thread::Thread() :
- m_thread(NULL),
- m_threadId(0),
- m_isRunning(false)
-{
-}
-
-Thread::~Thread()
-{
- if(m_thread) {
- CloseHandle(m_thread);
- }
-}
-
-bool
-Thread::start()
-{
- m_isRunning = true;
- m_thread = CreateThread(NULL, 0, &Thread::thread_main, this, 0, &m_threadId);
- if(!m_thread) {
- m_isRunning = false;
- }
- return m_isRunning;
-}
-
-bool
-Thread::wait(int *exitStatus)
-{
- if (!m_isRunning) {
- return false;
- }
-
- if(WaitForSingleObject(m_thread, INFINITE) == WAIT_FAILED) {
- return false;
- }
-
- DWORD retval;
- if (!GetExitCodeThread(m_thread,&retval)) {
- return false;
- }
-
- m_isRunning = 0;
-
- if (exitStatus) {
- *exitStatus = retval;
- }
- return true;
-}
-
-bool
-Thread::trywait(int *exitStatus)
-{
- if (!m_isRunning) {
- return false;
- }
-
- if(WaitForSingleObject(m_thread, 0) == WAIT_OBJECT_0) {
-
- DWORD retval;
- if (!GetExitCodeThread(m_thread,&retval)) {
- return true;
- }
-
- if (exitStatus) {
- *exitStatus = retval;
- }
- return true;
- }
-
- return false;
-}
-
-DWORD WINAPI
-Thread::thread_main(void *p_arg)
-{
- Thread *self = (Thread *)p_arg;
- int ret = self->Main();
- self->m_isRunning = false;
- ::emugl::ThreadStore::OnThreadExit();
- return ret;
-}
-
-} // of namespace osUtils
diff --git a/emulator/opengl/shared/emugl/common/Android.mk b/emulator/opengl/shared/emugl/common/Android.mk
index 58dd6da..fb9ab57 100644
--- a/emulator/opengl/shared/emugl/common/Android.mk
+++ b/emulator/opengl/shared/emugl/common/Android.mk
@@ -9,16 +9,26 @@ commonSources := \
id_to_object_map.cpp \
lazy_instance.cpp \
pod_vector.cpp \
+ shared_library.cpp \
smart_ptr.cpp \
sockets.cpp \
thread_store.cpp \
host_commonSources := $(commonSources)
+host_commonLdLibs := -lstdc++
+
+ifneq (windows,$(HOST_OS))
+ host_commonSources += thread_pthread.cpp
+ host_commonLdLibs += -ldl -lpthread
+else
+ host_commonSources += thread_win32.cpp
+endif
+
$(call emugl-begin-host-static-library,libemugl_common)
LOCAL_SRC_FILES := $(host_commonSources)
$(call emugl-export,C_INCLUDES,$(EMUGL_PATH)/shared)
-$(call emugl-export,LDLIBS,-lstdc++)
+$(call emugl-export,LDLIBS,$(host_commonLdLibs))
$(call emugl-end-module)
ifdef EMUGL_BUILD_64BITS
@@ -26,7 +36,7 @@ ifdef EMUGL_BUILD_64BITS
LOCAL_SRC_FILES := $(host_commonSources)
$(call emugl-export,CFLAGS,-m64 -fPIC)
$(call emugl-export,C_INCLUDES,$(EMUGL_PATH)/shared)
- $(call emugl-export,LDLIBS,-lstdc++)
+ $(call emugl-export,LDLIBS,$(host_commonLdLibs))
$(call emugl-end-module)
endif
@@ -38,8 +48,10 @@ host_commonSources := \
lazy_instance_unittest.cpp \
pod_vector_unittest.cpp \
mutex_unittest.cpp \
+ shared_library_unittest.cpp \
smart_ptr_unittest.cpp \
thread_store_unittest.cpp \
+ thread_unittest.cpp \
$(call emugl-begin-host-executable,emugl_common_host_unittests)
LOCAL_SRC_FILES := $(host_commonSources)
@@ -52,3 +64,13 @@ ifdef EMUGL_BUILD_64BITS
$(call emugl-import,lib64emugl_common lib64emugl_gtest)
$(call emugl-end-module)
endif
+
+$(call emugl-begin-host-shared-library,libemugl_test_shared_library)
+LOCAL_SRC_FILES := testing/test_shared_library.cpp
+$(call emugl-end-module)
+
+ifdef EMUGL_BUILD_64BITS
+ $(call emugl-begin-host64-shared-library,lib64emugl_test_shared_library)
+ LOCAL_SRC_FILES := testing/test_shared_library.cpp
+ $(call emugl-end-module)
+endif
diff --git a/emulator/opengl/shared/emugl/common/shared_library.cpp b/emulator/opengl/shared/emugl/common/shared_library.cpp
new file mode 100644
index 0000000..db1c75c
--- /dev/null
+++ b/emulator/opengl/shared/emugl/common/shared_library.cpp
@@ -0,0 +1,105 @@
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "emugl/common/shared_library.h"
+
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+
+#ifndef _WIN32
+#include <dlfcn.h>
+#include <stdlib.h>
+#endif
+
+namespace emugl {
+
+#ifdef _WIN32
+
+// static
+SharedLibrary* SharedLibrary::open(const char* libraryName) {
+ HMODULE lib = LoadLibrary(libraryName);
+ return lib ? new SharedLibrary(lib) : NULL;
+}
+
+SharedLibrary::SharedLibrary(HandleType lib) : mLib(lib) {}
+
+SharedLibrary::~SharedLibrary() {
+ if (mLib) {
+ FreeLibrary(mLib);
+ }
+}
+
+SharedLibrary::FunctionPtr SharedLibrary::findSymbol(
+ const char* symbolName) {
+ if (!mLib || !symbolName) {
+ return NULL;
+ }
+ return reinterpret_cast<FunctionPtr>(
+ GetProcAddress(mLib, symbolName));
+}
+
+#else // !_WIN32
+
+// static
+SharedLibrary* SharedLibrary::open(const char* libraryName) {
+ const char* libPath = libraryName;
+ char* path = NULL;
+
+ const char* libBaseName = strrchr(libraryName, '/');
+ if (!libBaseName) {
+ libBaseName = libraryName;
+ }
+
+ if (!strchr(libBaseName, '.')) {
+ // There is no extension in this library name, so append one.
+#ifdef __APPLE__
+ static const char kDllExtension[] = ".dylib";
+#else
+ static const char kDllExtension[] = ".so";
+#endif
+ size_t pathLen = strlen(libraryName) + sizeof(kDllExtension);
+ path = static_cast<char*>(malloc(pathLen));
+ snprintf(path, pathLen, "%s%s", libraryName, kDllExtension);
+ libPath = path;
+ }
+
+ void* lib = dlopen(libPath, RTLD_NOW);
+
+ if (path) {
+ free(path);
+ }
+
+ return lib ? new SharedLibrary(lib) : NULL;
+}
+
+SharedLibrary::SharedLibrary(HandleType lib) : mLib(lib) {}
+
+SharedLibrary::~SharedLibrary() {
+ if (mLib) {
+ dlclose(mLib);
+ }
+}
+
+SharedLibrary::FunctionPtr SharedLibrary::findSymbol(
+ const char* symbolName) {
+ if (!mLib || !symbolName) {
+ return NULL;
+ }
+ return reinterpret_cast<FunctionPtr>(dlsym(mLib, symbolName));
+}
+
+#endif // !_WIN32
+
+} // namespace emugl
diff --git a/emulator/opengl/shared/emugl/common/shared_library.h b/emulator/opengl/shared/emugl/common/shared_library.h
new file mode 100644
index 0000000..38d25bd
--- /dev/null
+++ b/emulator/opengl/shared/emugl/common/shared_library.h
@@ -0,0 +1,85 @@
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef EMUGL_COMMON_SHARED_LIBRARY_H
+#define EMUGL_COMMON_SHARED_LIBRARY_H
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+namespace emugl {
+
+// A class used to open a platform-specific shared library, and probe
+// it for symbols. Usage is the following:
+//
+// // Open the library.
+// SharedLibrary* library = SharedLibrary::open("libFoo");
+// if (!library) {
+// ... could not find / open library!
+// }
+//
+// //Probe for function symbol.
+// FunctionPtr my_func = library->findSymbol("my_func");
+//
+// // Closes library/
+// delete library;
+//
+class SharedLibrary {
+public:
+ // Open a given library. |libraryName| can be either a full library
+ // path, or a simple name without an extension. On success, returns
+ // a new SharedLibrary instance that must be deleted by the caller.
+ static SharedLibrary* open(const char* libraryName);
+
+ // Closes an existing SharedLibrary instance.
+ ~SharedLibrary();
+
+ // Generic function pointer type, for values returned by the
+ // findSymbol() method.
+ typedef void (*FunctionPtr)(void);
+
+ // Probe a given SharedLibrary instance to find a symbol named
+ // |symbolName| in it. Return its address as a FunctionPtr, or
+ // NULL if the symbol is not found.
+ FunctionPtr findSymbol(const char* symbolName);
+
+private:
+#ifdef _WIN32
+ typedef HMODULE HandleType;
+#else
+ typedef void* HandleType;
+#endif
+
+ // Constructor intentionally hidden.
+ SharedLibrary(HandleType);
+
+ HandleType mLib;
+};
+
+// Macro to compose emugl shared library name under various OS and bitness
+// eg.
+// on x86_64, EMUGL_LIBNAME("foo") --> "lib64foo"
+
+#if defined(__x86_64__)
+# define EMUGL_LIBNAME(name) "lib64" name
+#elif defined(__i386__)
+# define EMUGL_LIBNAME(name) "lib" name
+#else
+/* This header is included by target w/o using EMUGL_LIBNAME(). Don't #error, leave it undefined */
+#endif
+
+} // namespace emugl
+
+#endif // EMUGL_COMMON_SHARED_LIBRARY_H
diff --git a/emulator/opengl/shared/emugl/common/shared_library_unittest.cpp b/emulator/opengl/shared/emugl/common/shared_library_unittest.cpp
new file mode 100644
index 0000000..cec4c73
--- /dev/null
+++ b/emulator/opengl/shared/emugl/common/shared_library_unittest.cpp
@@ -0,0 +1,141 @@
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "emugl/common/shared_library.h"
+
+#include <gtest/gtest.h>
+
+#include <string>
+
+#include <limits.h>
+#include <string.h>
+
+// Hack to get the current executable's full path.
+namespace testing {
+namespace internal {
+
+extern std::string g_executable_path;
+
+} // namespace internal
+} // namespace testing
+
+namespace emugl {
+
+namespace {
+
+// Return the name/path of the test shared library to load.
+// Note that this doesn't include a platform-specific extension.
+// This assumes that the test shared library is under the lib/ sub-directory
+// of the current executable's path!
+std::string GetTestLibraryName() {
+ static const char kSubDir[] = "lib/";
+#ifdef __x86_64__
+ static const char kLibraryPrefix[] = "lib64";
+#else
+ static const char kLibraryPrefix[] = "lib";
+#endif
+ static const char kTestLibrarySuffix[] = "emugl_test_shared_library";
+
+ const char* exec_path = testing::internal::g_executable_path.c_str();
+
+#ifdef _WIN32
+ const char* p = strrchr(exec_path, '/');
+ const char* p2 = strrchr(exec_path, '\\');
+ if (p2) {
+ if (!p || p2 > p) {
+ p = p2;
+ }
+ }
+#else
+ const char* p = strrchr(exec_path, '/');
+#endif
+
+ std::string path;
+
+ if (!p) {
+ path = "./";
+ } else {
+ path = std::string(exec_path, p - exec_path + 1U);
+ }
+ path += kSubDir;
+ path += kLibraryPrefix;
+ path += kTestLibrarySuffix;
+ printf("Library path: %s\n", path.c_str());
+ return path;
+}
+
+class SharedLibraryTest : public testing::Test {
+public:
+ SharedLibraryTest() {
+ // Locate the shared library
+ mLibraryPath = GetTestLibraryName();
+ }
+
+ ~SharedLibraryTest() {}
+
+ const char* library_path() const { return mLibraryPath.c_str(); }
+
+private:
+ std::string mLibraryPath;
+};
+
+class ScopedSharedLibrary {
+public:
+ explicit ScopedSharedLibrary(SharedLibrary* lib) : mLib(lib) {}
+ ~ScopedSharedLibrary() {
+ delete mLib;
+ }
+ SharedLibrary* get() const { return mLib; }
+
+ SharedLibrary* operator->() { return mLib; }
+
+private:
+ SharedLibrary* mLib;
+};
+
+} // namespace
+
+TEST_F(SharedLibraryTest, Open) {
+ ScopedSharedLibrary lib(SharedLibrary::open(library_path()));
+ EXPECT_TRUE(lib.get());
+}
+
+TEST_F(SharedLibraryTest, OpenWithExtension) {
+ std::string path = library_path();
+#ifdef _WIN32
+ path += ".dll";
+#elif defined(__APPLE__)
+ path += ".dylib";
+#else
+ path += ".so";
+#endif
+ ScopedSharedLibrary lib(SharedLibrary::open(path.c_str()));
+ EXPECT_TRUE(lib.get());
+}
+
+TEST_F(SharedLibraryTest, FindSymbol) {
+ ScopedSharedLibrary lib(SharedLibrary::open(library_path()));
+ EXPECT_TRUE(lib.get());
+
+ if (lib.get()) {
+ typedef int (*FooFunction)(void);
+
+ FooFunction foo_func = reinterpret_cast<FooFunction>(
+ lib->findSymbol("foo_function"));
+ EXPECT_TRUE(foo_func);
+ EXPECT_EQ(42, (*foo_func)());
+ }
+}
+
+} // namespace emugl
diff --git a/emulator/opengl/shared/emugl/common/testing/test_shared_library.cpp b/emulator/opengl/shared/emugl/common/testing/test_shared_library.cpp
new file mode 100644
index 0000000..598a963
--- /dev/null
+++ b/emulator/opengl/shared/emugl/common/testing/test_shared_library.cpp
@@ -0,0 +1,22 @@
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// This source file must be compiled into a simple shared library which
+// will be used by shared_library_unittest.cpp to verify that the
+// emugl::SharedLibrary class works properly.
+
+
+extern "C" int foo_function(void) {
+ return 42;
+}
diff --git a/emulator/opengl/shared/emugl/common/thread.h b/emulator/opengl/shared/emugl/common/thread.h
new file mode 100644
index 0000000..d0f7d20
--- /dev/null
+++ b/emulator/opengl/shared/emugl/common/thread.h
@@ -0,0 +1,102 @@
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef EMUGL_COMMON_THREAD_H
+#define EMUGL_COMMON_THREAD_H
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <pthread.h>
+#endif
+
+#include <stdint.h>
+
+namespace emugl {
+
+// Wrapper class for platform-specific threads.
+// To create your own thread, define a sub-class of emugl::Thread
+// and override its main() method.
+//
+// For example:
+//
+// class MyThread : public emugl::Thread {
+// public:
+// MyThread() : Thread() {}
+//
+// virtual intptr_t main() {
+// ... main thread loop implementation
+// return 0;
+// }
+// };
+//
+// ...
+//
+// // Create new instance, but does not start it.
+// MyThread* thread = new MyThread();
+//
+// // Start the thread.
+// thread->start();
+//
+// // Wait for thread completion, and gets result into |exitStatus|.
+// int exitStatus;
+// thread->wait(&exitStatus);
+//
+class Thread {
+public:
+ // Public constructor.
+ Thread();
+
+ // Virtual destructor.
+ virtual ~Thread();
+
+ // Override this method in your own thread sub-classes. This will
+ // be called when start() is invoked on the Thread instance.
+ virtual intptr_t main() = 0;
+
+ // Start a thread instance. Return true on success, false otherwise
+ // (e.g. if the thread was already started or terminated).
+ bool start();
+
+ // Wait for thread termination and retrieve exist status into
+ // |*exitStatus|. Return true on success, false otherwise.
+ // NOTE: |exitStatus| can be NULL.
+ bool wait(intptr_t *exitStatus);
+
+ // Check whether a thread has terminated. On success, return true
+ // and sets |*exitStatus|. On failure, return false.
+ // NOTE: |exitStatus| can be NULL.
+ bool tryWait(intptr_t *exitStatus);
+
+private:
+#ifdef _WIN32
+ static DWORD WINAPI thread_main(void* arg);
+
+ HANDLE mThread;
+ DWORD mThreadId;
+ CRITICAL_SECTION mLock;
+#else // !WIN32
+ static void* thread_main(void* arg);
+
+ pthread_t mThread;
+ pthread_mutex_t mLock;
+#endif
+ intptr_t mExitStatus;
+ bool mIsRunning;
+};
+
+} // namespace emugl
+
+#endif // EMUGL_COMMON_THREAD_H
+
diff --git a/emulator/opengl/shared/emugl/common/thread_pthread.cpp b/emulator/opengl/shared/emugl/common/thread_pthread.cpp
new file mode 100644
index 0000000..5dbc3ab
--- /dev/null
+++ b/emulator/opengl/shared/emugl/common/thread_pthread.cpp
@@ -0,0 +1,114 @@
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "emugl/common/thread.h"
+
+#include "emugl/common/thread_store.h"
+
+#include <stdio.h>
+
+namespace emugl {
+
+namespace {
+
+class ScopedLocker {
+public:
+ ScopedLocker(pthread_mutex_t* mutex) : mMutex(mutex) {
+ pthread_mutex_lock(mMutex);
+ }
+
+ ~ScopedLocker() {
+ pthread_mutex_unlock(mMutex);
+ }
+private:
+ pthread_mutex_t* mMutex;
+};
+
+} // namespace
+
+Thread::Thread() :
+ mThread((pthread_t)NULL),
+ mExitStatus(0),
+ mIsRunning(false) {
+ pthread_mutex_init(&mLock, NULL);
+}
+
+Thread::~Thread() {
+ pthread_mutex_destroy(&mLock);
+}
+
+bool Thread::start() {
+ bool ret = true;
+ pthread_mutex_lock(&mLock);
+ mIsRunning = true;
+ if (pthread_create(&mThread, NULL, thread_main, this)) {
+ ret = false;
+ mIsRunning = false;
+ }
+ pthread_mutex_unlock(&mLock);
+ return ret;
+}
+
+bool Thread::wait(intptr_t *exitStatus) {
+ {
+ ScopedLocker locker(&mLock);
+ if (!mIsRunning) {
+ // Thread already stopped.
+ if (exitStatus) {
+ *exitStatus = mExitStatus;
+ }
+ return true;
+ }
+ }
+
+ // NOTE: Do not hold the lock when waiting for the thread to ensure
+ // it can update mIsRunning and mExitStatus properly in thread_main
+ // without blocking.
+ void *retval;
+ if (pthread_join(mThread, &retval)) {
+ return false;
+ }
+ if (exitStatus) {
+ *exitStatus = (intptr_t)retval;
+ }
+ return true;
+}
+
+bool Thread::tryWait(intptr_t *exitStatus) {
+ ScopedLocker locker(&mLock);
+ if (!mIsRunning) {
+ return false;
+ }
+ if (exitStatus) {
+ *exitStatus = mExitStatus;
+ }
+ return true;
+}
+
+// static
+void* Thread::thread_main(void *arg) {
+ Thread* self = reinterpret_cast<Thread*>(arg);
+ intptr_t ret = self->main();
+
+ pthread_mutex_lock(&self->mLock);
+ self->mIsRunning = false;
+ self->mExitStatus = ret;
+ pthread_mutex_unlock(&self->mLock);
+
+ ::emugl::ThreadStore::OnThreadExit();
+
+ return (void*)ret;
+}
+
+} // namespace emugl
diff --git a/emulator/opengl/shared/emugl/common/thread_unittest.cpp b/emulator/opengl/shared/emugl/common/thread_unittest.cpp
new file mode 100644
index 0000000..db1931f
--- /dev/null
+++ b/emulator/opengl/shared/emugl/common/thread_unittest.cpp
@@ -0,0 +1,109 @@
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "emugl/common/thread.h"
+
+#include "emugl/common/mutex.h"
+
+#include <gtest/gtest.h>
+
+namespace emugl {
+
+namespace {
+
+// A simple thread instance that does nothing at all and exits immediately.
+class EmptyThread : public ::emugl::Thread {
+public:
+ intptr_t main() { return 42; }
+};
+
+class CountingThread : public ::emugl::Thread {
+public:
+ class State {
+ public:
+ State() : mLock(), mCount(0) {}
+ ~State() {}
+
+ void increment() {
+ mLock.lock();
+ mCount++;
+ mLock.unlock();
+ }
+
+ int count() const {
+ int ret;
+ mLock.lock();
+ ret = mCount;
+ mLock.unlock();
+ return ret;
+ }
+
+ private:
+ mutable Mutex mLock;
+ int mCount;
+ };
+
+ CountingThread(State* state) : mState(state) {}
+
+ intptr_t main() {
+ mState->increment();
+ return 0;
+ }
+
+private:
+ State* mState;
+};
+
+} // namespace
+
+TEST(ThreadTest, SimpleThread) {
+ Thread* thread = new EmptyThread();
+ EXPECT_TRUE(thread);
+ EXPECT_TRUE(thread->start());
+ intptr_t status;
+ EXPECT_TRUE(thread->wait(&status));
+ EXPECT_EQ(42, status);
+}
+
+TEST(ThreadTest, MultipleThreads) {
+ CountingThread::State state;
+ const size_t kMaxThreads = 100;
+ Thread* threads[kMaxThreads];
+
+ // Create all threads.
+ for (size_t n = 0; n < kMaxThreads; ++n) {
+ threads[n] = new CountingThread(&state);
+ EXPECT_TRUE(threads[n]) << "thread " << n;
+ }
+
+ // Start them all.
+ for (size_t n = 0; n < kMaxThreads; ++n) {
+ EXPECT_TRUE(threads[n]->start()) << "thread " << n;
+ }
+
+ // Wait for them all.
+ for (size_t n = 0; n < kMaxThreads; ++n) {
+ EXPECT_TRUE(threads[n]->wait(NULL)) << "thread " << n;
+ }
+
+ // Check state.
+ EXPECT_EQ((int)kMaxThreads, state.count());
+
+ // Delete them all.
+ for (size_t n = 0; n < kMaxThreads; ++n) {
+ delete threads[n];
+ }
+}
+
+} // namespace emugl
diff --git a/emulator/opengl/shared/emugl/common/thread_win32.cpp b/emulator/opengl/shared/emugl/common/thread_win32.cpp
new file mode 100644
index 0000000..f348ca8
--- /dev/null
+++ b/emulator/opengl/shared/emugl/common/thread_win32.cpp
@@ -0,0 +1,122 @@
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "emugl/common/thread.h"
+
+#include "emugl/common/thread_store.h"
+
+namespace emugl {
+
+namespace {
+
+class ScopedLocker {
+public:
+ ScopedLocker(CRITICAL_SECTION* section) : mSection(section) {
+ EnterCriticalSection(mSection);
+ }
+
+ ~ScopedLocker() {
+ LeaveCriticalSection(mSection);
+ }
+private:
+ CRITICAL_SECTION* mSection;
+};
+
+} // namespace
+
+Thread::Thread() :
+ mThread(INVALID_HANDLE_VALUE),
+ mThreadId(0),
+ mExitStatus(0),
+ mIsRunning(false) {
+ InitializeCriticalSection(&mLock);
+}
+
+Thread::~Thread() {
+ if(mThread != INVALID_HANDLE_VALUE) {
+ CloseHandle(mThread);
+ }
+ DeleteCriticalSection(&mLock);
+}
+
+bool Thread::start() {
+ ScopedLocker locker(&mLock);
+
+ bool ret = true;
+ mIsRunning = true;
+ mThread = CreateThread(NULL, 0, &Thread::thread_main, this, 0, &mThreadId);
+ if (!mThread) {
+ ret = false;
+ mIsRunning = false;
+ }
+ return ret;
+}
+
+bool Thread::wait(intptr_t* exitStatus) {
+ {
+ ScopedLocker locker(&mLock);
+ if (!mIsRunning) {
+ // Thread already stopped.
+ if (exitStatus) {
+ *exitStatus = mExitStatus;
+ }
+ return true;
+ }
+ }
+
+ // NOTE: Do not hold lock during wait to aloow thread_main to
+ // properly update mIsRunning and mExitStatus on thread exit.
+ if (WaitForSingleObject(mThread, INFINITE) == WAIT_FAILED) {
+ return false;
+ }
+
+ if (exitStatus) {
+ ScopedLocker locker(&mLock);
+ *exitStatus = mExitStatus;
+ }
+ return true;
+}
+
+bool Thread::tryWait(intptr_t* exitStatus) {
+ ScopedLocker locker(&mLock);
+
+ if (!mIsRunning ||
+ WaitForSingleObject(mThread, 0) != WAIT_OBJECT_0) {
+ return false;
+ }
+
+ if (exitStatus) {
+ *exitStatus = mExitStatus;
+ }
+ return true;
+}
+
+// static
+DWORD WINAPI Thread::thread_main(void *arg)
+{
+ Thread* self = reinterpret_cast<Thread*>(arg);
+ intptr_t ret = self->main();
+
+ EnterCriticalSection(&self->mLock);
+ self->mIsRunning = false;
+ self->mExitStatus = ret;
+ LeaveCriticalSection(&self->mLock);
+
+ // Ensure all thread-local values are released for this thread.
+ ::emugl::ThreadStore::OnThreadExit();
+
+ return static_cast<DWORD>(ret);
+}
+
+} // namespace emugl