1/*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. 9 * 10 * This software is licensed as described in the file COPYING, which 11 * you should have received as part of this distribution. The terms 12 * are also available at http://curl.haxx.se/docs/copyright.html. 13 * 14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 15 * copies of the Software, and permit persons to whom the Software is 16 * furnished to do so, under the terms of the COPYING file. 17 * 18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 * KIND, either express or implied. 20 * 21 ***************************************************************************/ 22#include "setup.h" 23 24#if defined(USE_THREADS_POSIX) 25# ifdef HAVE_PTHREAD_H 26# include <pthread.h> 27# endif 28#elif defined(USE_THREADS_WIN32) 29# ifdef HAVE_PROCESS_H 30# include <process.h> 31# endif 32#endif 33 34#include "curl_threads.h" 35 36#define _MPRINTF_REPLACE /* use our functions only */ 37#include <curl/mprintf.h> 38 39#include "curl_memory.h" 40/* The last #include file should be: */ 41#include "memdebug.h" 42 43#if defined(USE_THREADS_POSIX) 44 45struct curl_actual_call { 46 unsigned int (*func)(void *); 47 void *arg; 48}; 49 50static void *curl_thread_create_thunk(void *arg) 51{ 52 struct curl_actual_call * ac = arg; 53 unsigned int (*func)(void *) = ac->func; 54 void *real_arg = ac->arg; 55 56 free(ac); 57 58 (*func)(real_arg); 59 60 return 0; 61} 62 63curl_thread_t Curl_thread_create(unsigned int (*func) (void*), void *arg) 64{ 65 curl_thread_t t; 66 struct curl_actual_call *ac = malloc(sizeof(struct curl_actual_call)); 67 if(!ac) 68 return curl_thread_t_null; 69 70 ac->func = func; 71 ac->arg = arg; 72 73 if(pthread_create(&t, NULL, curl_thread_create_thunk, ac) != 0) { 74 free(ac); 75 return curl_thread_t_null; 76 } 77 78 return t; 79} 80 81void Curl_thread_destroy(curl_thread_t hnd) 82{ 83 if(hnd != curl_thread_t_null) 84 pthread_detach(hnd); 85} 86 87int Curl_thread_join(curl_thread_t *hnd) 88{ 89 int ret = (pthread_join(*hnd, NULL) == 0); 90 91 *hnd = curl_thread_t_null; 92 93 return ret; 94} 95 96#elif defined(USE_THREADS_WIN32) 97 98curl_thread_t Curl_thread_create(unsigned int (CURL_STDCALL *func) (void*), 99 void *arg) 100{ 101#ifdef _WIN32_WCE 102 return CreateThread(NULL, 0, func, arg, 0, NULL); 103#else 104 curl_thread_t t; 105 t = (curl_thread_t)_beginthreadex(NULL, 0, func, arg, 0, NULL); 106 if((t == 0) || (t == (curl_thread_t)-1L)) 107 return curl_thread_t_null; 108 return t; 109#endif 110} 111 112void Curl_thread_destroy(curl_thread_t hnd) 113{ 114 CloseHandle(hnd); 115} 116 117int Curl_thread_join(curl_thread_t *hnd) 118{ 119 int ret = (WaitForSingleObject(*hnd, INFINITE) == WAIT_OBJECT_0); 120 121 Curl_thread_destroy(*hnd); 122 123 *hnd = curl_thread_t_null; 124 125 return ret; 126} 127 128#endif /* USE_THREADS_* */ 129