1/*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 1998 - 2013, 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 = malloc(sizeof(pthread_t)); 67 struct curl_actual_call *ac = malloc(sizeof(struct curl_actual_call)); 68 if(!(ac && t)) 69 goto err; 70 71 ac->func = func; 72 ac->arg = arg; 73 74 if(pthread_create(t, NULL, curl_thread_create_thunk, ac) != 0) 75 goto err; 76 77 return t; 78 79err: 80 Curl_safefree(t); 81 Curl_safefree(ac); 82 return curl_thread_t_null; 83} 84 85void Curl_thread_destroy(curl_thread_t hnd) 86{ 87 if(hnd != curl_thread_t_null) { 88 pthread_detach(*hnd); 89 free(hnd); 90 } 91} 92 93int Curl_thread_join(curl_thread_t *hnd) 94{ 95 int ret = (pthread_join(**hnd, NULL) == 0); 96 97 free(*hnd); 98 *hnd = curl_thread_t_null; 99 100 return ret; 101} 102 103#elif defined(USE_THREADS_WIN32) 104 105curl_thread_t Curl_thread_create(unsigned int (CURL_STDCALL *func) (void*), 106 void *arg) 107{ 108#ifdef _WIN32_WCE 109 return CreateThread(NULL, 0, func, arg, 0, NULL); 110#else 111 curl_thread_t t; 112 t = (curl_thread_t)_beginthreadex(NULL, 0, func, arg, 0, NULL); 113 if((t == 0) || (t == (curl_thread_t)-1L)) 114 return curl_thread_t_null; 115 return t; 116#endif 117} 118 119void Curl_thread_destroy(curl_thread_t hnd) 120{ 121 CloseHandle(hnd); 122} 123 124int Curl_thread_join(curl_thread_t *hnd) 125{ 126 int ret = (WaitForSingleObject(*hnd, INFINITE) == WAIT_OBJECT_0); 127 128 Curl_thread_destroy(*hnd); 129 130 *hnd = curl_thread_t_null; 131 132 return ret; 133} 134 135#endif /* USE_THREADS_* */ 136