/**************************************************************************\ * * This file is part of the Coin 3D visualization library. * Copyright (C) 1998-2007 by Systems in Motion. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * ("GPL") version 2 as published by the Free Software Foundation. * See the file LICENSE.GPL at the root directory of this source * distribution for additional information about the GNU GPL. * * For using Coin with software that can not be combined with the GNU * GPL, and for taking advantage of the additional benefits of our * support services, please contact Systems in Motion about acquiring * a Coin Professional Edition License. * * See http://www.coin3d.org/ for more information. * * Systems in Motion, Postboks 1283, Pirsenteret, 7462 Trondheim, NORWAY. * http://www.sim.no/ sales@sim.no coin-support@coin3d.org * \**************************************************************************/ /* this file should only be included from thread.c */ #include static DWORD WINAPI cc_w32thread_thread_proc(LPVOID lpParameter) { cc_thread *thread = (cc_thread *)lpParameter; return (DWORD) thread->func(thread->closure); } static int internal_init(cc_thread * thread) { DWORD threadid_unused; thread->w32thread.threadhandle = CreateThread(NULL, 0, cc_w32thread_thread_proc, (LPVOID) thread, 0, &threadid_unused); /* threadid_unused - see PlatformSDK doc. for CreateThread */ /* FIXME: thammer 20011108, check PlatformSDK doc for * _beginthreadex, _endthreadex, and note about using these with * LIBCMT.LIB "A thread that uses functions from the C run-time * libraries should use the beginthread and endthread C run-time * functions for thread management rather than CreateThread and * ExitThread. Failure to do so results in small memory leaks when * ExitThread is called. " */ if (thread->w32thread.threadhandle == NULL) { if (COIN_DEBUG) { cc_win32_print_error("internal_init", "CreateThread()", GetLastError()); } return CC_ERROR; } return CC_OK; } static int internal_clean(cc_thread * thread_struct) { /* FIXME: Is there really nothing to do here? pederb, 2001-12-10 */ return CC_OK; } static int internal_join(cc_thread * thread, void ** retvalptr) { DWORD status; BOOL bstatus; DWORD exitcode; status = WaitForSingleObject(thread->w32thread.threadhandle, INFINITE); if (status == WAIT_FAILED) { if (COIN_DEBUG) { cc_win32_print_error("internal_join", "WaitForSingleObject()", GetLastError()); } return CC_ERROR; } else if (status != WAIT_OBJECT_0) { if (COIN_DEBUG) { cc_debugerror_post("internal_join", "WaitForSingleObject() - unknown return value: %d\n", status); } return CC_ERROR; } bstatus = GetExitCodeThread(thread->w32thread.threadhandle, &exitcode); if (bstatus == FALSE) { if (COIN_DEBUG) { cc_win32_print_error("internal_join", "GetExitCodeThread()", GetLastError()); } } else if (retvalptr) { *retvalptr = (void *)exitcode; } /* termination could be forced with TerminateThread() - but this * will result in memory leaks - or bigger problems - see Platform * SDK doc. */ CloseHandle(thread->w32thread.threadhandle); thread->w32thread.threadhandle = NULL; return bstatus ? CC_OK : CC_ERROR; }