xref: /openbsd-src/gnu/usr.bin/perl/win32/win32thread.c (revision db3296cf5c1dd9058ceecc3a29fe4aaa0bd26000)
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