diff options
Diffstat (limited to 'emulator/opengl/shared/OpenglOsUtils')
-rw-r--r-- | emulator/opengl/shared/OpenglOsUtils/Android.mk | 57 | ||||
-rw-r--r-- | emulator/opengl/shared/OpenglOsUtils/osDynLibrary.cpp | 79 | ||||
-rw-r--r-- | emulator/opengl/shared/OpenglOsUtils/osDynLibrary.h | 71 | ||||
-rw-r--r-- | emulator/opengl/shared/OpenglOsUtils/osProcess.h | 62 | ||||
-rw-r--r-- | emulator/opengl/shared/OpenglOsUtils/osProcessUnix.cpp | 210 | ||||
-rw-r--r-- | emulator/opengl/shared/OpenglOsUtils/osProcessWin.cpp | 171 | ||||
-rw-r--r-- | emulator/opengl/shared/OpenglOsUtils/osThread.h | 60 | ||||
-rw-r--r-- | emulator/opengl/shared/OpenglOsUtils/osThreadUnix.cpp | 94 | ||||
-rw-r--r-- | emulator/opengl/shared/OpenglOsUtils/osThreadWin.cpp | 101 |
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 |