aboutsummaryrefslogtreecommitdiffstats
path: root/emulator/opengl/shared/OpenglOsUtils
diff options
context:
space:
mode:
Diffstat (limited to 'emulator/opengl/shared/OpenglOsUtils')
-rw-r--r--emulator/opengl/shared/OpenglOsUtils/Android.mk57
-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.cpp94
-rw-r--r--emulator/opengl/shared/OpenglOsUtils/osThreadWin.cpp101
9 files changed, 905 insertions, 0 deletions
diff --git a/emulator/opengl/shared/OpenglOsUtils/Android.mk b/emulator/opengl/shared/OpenglOsUtils/Android.mk
new file mode 100644
index 0000000..82391cd
--- /dev/null
+++ b/emulator/opengl/shared/OpenglOsUtils/Android.mk
@@ -0,0 +1,57 @@
+# 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)
+
+### Guest library ##############################################
+$(call emugl-begin-static-library,libOpenglOsUtils)
+
+ $(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
+ $(call emugl-export,LDLIBS,-ldl)
+
+ LOCAL_SRC_FILES := \
+ osProcessUnix.cpp \
+ osThreadUnix.cpp \
+ osDynLibrary.cpp
+
+$(call emugl-end-module)
+
+
+### Host library ##############################################
+
+host_common_SRC_FILES := osDynLibrary.cpp
+host_common_LDLIBS :=
+
+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
+endif
+
+### 32-bit host library ####
+$(call emugl-begin-host-static-library,libOpenglOsUtils)
+ $(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
+ LOCAL_SRC_FILES = $(host_common_SRC_FILES)
+ $(call emugl-export,LDLIBS,$(host_common_LDLIBS))
+$(call emugl-end-module)
+
+### 64-bit host library ####
+$(call emugl-begin-host-static-library,lib64OpenglOsUtils)
+ $(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
+ LOCAL_SRC_FILES = $(host_common_SRC_FILES)
+ $(call emugl-export,LDLIBS,$(host_common_LDLIBS))
+ $(call emugl-export,CFLAGS,-m64)
+$(call emugl-end-module)
diff --git a/emulator/opengl/shared/OpenglOsUtils/osDynLibrary.cpp b/emulator/opengl/shared/OpenglOsUtils/osDynLibrary.cpp
new file mode 100644
index 0000000..e8e6ab7
--- /dev/null
+++ b/emulator/opengl/shared/OpenglOsUtils/osDynLibrary.cpp
@@ -0,0 +1,79 @@
+/*
+* 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
new file mode 100644
index 0000000..c83fbf3
--- /dev/null
+++ b/emulator/opengl/shared/OpenglOsUtils/osDynLibrary.h
@@ -0,0 +1,71 @@
+/*
+* 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
new file mode 100644
index 0000000..82b31b3
--- /dev/null
+++ b/emulator/opengl/shared/OpenglOsUtils/osProcess.h
@@ -0,0 +1,62 @@
+/*
+* 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
new file mode 100644
index 0000000..c97ff58
--- /dev/null
+++ b/emulator/opengl/shared/OpenglOsUtils/osProcessUnix.cpp
@@ -0,0 +1,210 @@
+/*
+* 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
new file mode 100644
index 0000000..6ff0fdf
--- /dev/null
+++ b/emulator/opengl/shared/OpenglOsUtils/osProcessWin.cpp
@@ -0,0 +1,171 @@
+/*
+* 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
new file mode 100644
index 0000000..970396d
--- /dev/null
+++ b/emulator/opengl/shared/OpenglOsUtils/osThread.h
@@ -0,0 +1,60 @@
+/*
+* 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
new file mode 100644
index 0000000..d8879eb
--- /dev/null
+++ b/emulator/opengl/shared/OpenglOsUtils/osThreadUnix.cpp
@@ -0,0 +1,94 @@
+/*
+* 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"
+
+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;
+ }
+
+ long long int ret=(long long int)retval;
+ if (exitStatus) {
+ *exitStatus = (int)ret;
+ }
+ 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);
+
+ return (void*)ret;
+}
+
+} // of namespace osUtils
+
diff --git a/emulator/opengl/shared/OpenglOsUtils/osThreadWin.cpp b/emulator/opengl/shared/OpenglOsUtils/osThreadWin.cpp
new file mode 100644
index 0000000..2d563f8
--- /dev/null
+++ b/emulator/opengl/shared/OpenglOsUtils/osThreadWin.cpp
@@ -0,0 +1,101 @@
+/*
+* 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"
+
+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;
+ return ret;
+}
+
+} // of namespace osUtils