1 #include "EXTERN.h" 2 #include "perl.h" 3 4 #ifdef USE_DECLSPEC_THREAD 5 __declspec(thread) void *PL_current_context = NULL; 6 #endif 7 8 void 9 Perl_set_context(void *t) 10 { 11 #if defined(USE_5005THREADS) || defined(USE_ITHREADS) 12 # ifdef USE_DECLSPEC_THREAD 13 Perl_current_context = t; 14 # else 15 DWORD err = GetLastError(); 16 TlsSetValue(PL_thr_key,t); 17 SetLastError(err); 18 # endif 19 #endif 20 } 21 22 void * 23 Perl_get_context(void) 24 { 25 #if defined(USE_5005THREADS) || defined(USE_ITHREADS) 26 # ifdef USE_DECLSPEC_THREAD 27 return Perl_current_context; 28 # else 29 DWORD err = GetLastError(); 30 void *result = TlsGetValue(PL_thr_key); 31 SetLastError(err); 32 return result; 33 # endif 34 #else 35 return NULL; 36 #endif 37 } 38 39 #ifdef USE_5005THREADS 40 void 41 Perl_init_thread_intern(struct perl_thread *athr) 42 { 43 #ifndef USE_DECLSPEC_THREAD 44 45 /* 46 * Initialize port-specific per-thread data in thr->i 47 * as only things we have there are just static areas for 48 * return values we don't _need_ to do anything but 49 * this is good practice: 50 */ 51 memset(&athr->i,0,sizeof(athr->i)); 52 53 #endif 54 } 55 56 void 57 Perl_set_thread_self(struct perl_thread *thr) 58 { 59 /* Set thr->self. GetCurrentThread() retrurns a pseudo handle, need 60 this to convert it into a handle another thread can use. 61 */ 62 DuplicateHandle(GetCurrentProcess(), 63 GetCurrentThread(), 64 GetCurrentProcess(), 65 &thr->self, 66 0, 67 FALSE, 68 DUPLICATE_SAME_ACCESS); 69 } 70 71 int 72 Perl_thread_create(struct perl_thread *thr, thread_func_t *fn) 73 { 74 DWORD junk; 75 unsigned long th; 76 77 DEBUG_S(PerlIO_printf(Perl_debug_log, 78 "%p: create OS thread\n", thr)); 79 #ifdef USE_RTL_THREAD_API 80 /* See comment about USE_RTL_THREAD_API in win32thread.h */ 81 #if defined(__BORLANDC__) 82 th = _beginthreadNT(fn, /* start address */ 83 0, /* stack size */ 84 (void *)thr, /* parameters */ 85 (void *)NULL, /* security attrib */ 86 0, /* creation flags */ 87 (unsigned long *)&junk); /* tid */ 88 if (th == (unsigned long)-1) 89 th = 0; 90 #elif defined(_MSC_VER_) 91 th = _beginthreadex((void *)NULL, /* security attrib */ 92 0, /* stack size */ 93 fn, /* start address */ 94 (void*)thr, /* parameters */ 95 0, /* creation flags */ 96 (unsigned *)&junk); /* tid */ 97 #else /* compilers using CRTDLL.DLL only have _beginthread() */ 98 th = _beginthread(fn, /* start address */ 99 0, /* stack size */ 100 (void*)thr); /* parameters */ 101 if (th == (unsigned long)-1) 102 th = 0; 103 #endif 104 thr->self = (HANDLE)th; 105 #else /* !USE_RTL_THREAD_API */ 106 thr->self = CreateThread(NULL, 0, fn, (void*)thr, 0, &junk); 107 #endif /* !USE_RTL_THREAD_API */ 108 DEBUG_S(PerlIO_printf(Perl_debug_log, 109 "%p: OS thread = %p, id=%ld\n", thr, thr->self, junk)); 110 return thr->self ? 0 : -1; 111 } 112 #endif 113 114