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 23#include "curl_setup.h" 24 25#if defined(USE_THREADS_POSIX) 26# ifdef HAVE_PTHREAD_H 27# include <pthread.h> 28# endif 29#elif defined(USE_THREADS_WIN32) 30# ifdef HAVE_PROCESS_H 31# include <process.h> 32# endif 33#endif 34 35#include "curl_threads.h" 36 37#define _MPRINTF_REPLACE /* use our functions only */ 38#include <curl/mprintf.h> 39 40#include "curl_memory.h" 41/* The last #include file should be: */ 42#include "memdebug.h" 43 44#if defined(USE_THREADS_POSIX) 45 46struct curl_actual_call { 47 unsigned int (*func)(void *); 48 void *arg; 49}; 50 51static void *curl_thread_create_thunk(void *arg) 52{ 53 struct curl_actual_call * ac = arg; 54 unsigned int (*func)(void *) = ac->func; 55 void *real_arg = ac->arg; 56 57 free(ac); 58 59 (*func)(real_arg); 60 61 return 0; 62} 63 64curl_thread_t Curl_thread_create(unsigned int (*func) (void*), void *arg) 65{ 66 curl_thread_t t; 67 struct curl_actual_call *ac = malloc(sizeof(struct curl_actual_call)); 68 if(!ac) 69 return curl_thread_t_null; 70 71 ac->func = func; 72 ac->arg = arg; 73 74 if(pthread_create(&t, NULL, curl_thread_create_thunk, ac) != 0) { 75 free(ac); 76 return curl_thread_t_null; 77 } 78 79 return t; 80} 81 82void Curl_thread_destroy(curl_thread_t hnd) 83{ 84 if(hnd != curl_thread_t_null) 85 pthread_detach(hnd); 86} 87 88int Curl_thread_join(curl_thread_t *hnd) 89{ 90 int ret = (pthread_join(*hnd, NULL) == 0); 91 92 *hnd = curl_thread_t_null; 93 94 return ret; 95} 96 97#elif defined(USE_THREADS_WIN32) 98 99curl_thread_t Curl_thread_create(unsigned int (CURL_STDCALL *func) (void*), 100 void *arg) 101{ 102#ifdef _WIN32_WCE 103 return CreateThread(NULL, 0, func, arg, 0, NULL); 104#else 105 curl_thread_t t; 106 t = (curl_thread_t)_beginthreadex(NULL, 0, func, arg, 0, NULL); 107 if((t == 0) || (t == (curl_thread_t)-1L)) 108 return curl_thread_t_null; 109 return t; 110#endif 111} 112 113void Curl_thread_destroy(curl_thread_t hnd) 114{ 115 CloseHandle(hnd); 116} 117 118int Curl_thread_join(curl_thread_t *hnd) 119{ 120 int ret = (WaitForSingleObject(*hnd, INFINITE) == WAIT_OBJECT_0); 121 122 Curl_thread_destroy(*hnd); 123 124 *hnd = curl_thread_t_null; 125 126 return ret; 127} 128 129#endif /* USE_THREADS_* */ 130