summaryrefslogtreecommitdiff
path: root/win32/win32thread.h
diff options
context:
space:
mode:
authorGurusamy Sarathy <gsar@cpan.org>1998-01-04 07:59:44 +0000
committerGurusamy Sarathy <gsar@cpan.org>1998-01-04 07:59:44 +0000
commit2d7a92375815264badaef23c612657cbd4799f31 (patch)
treea21bf70b8eb3f8982a62d2acf344771f2d96e952 /win32/win32thread.h
parent25931d335858f0e7767af03260b9bb9ad7a959d5 (diff)
downloadperl-2d7a92375815264badaef23c612657cbd4799f31.tar.gz
[win32] Various win32 fixes
- support spawn via system(&P_NOWAIT,...) like OS2 - support wait() and waitpid() - s/GetCurrentDirectory/GetCwd/, long-named XS to be removed - support -lfoo properly in ExtUtils::Liblist - fix outdated info about Win32 support in perlfaq2 - fix win32 bug in perldoc that causes spurious warnings - regularize global function/variable names yet more - fix bug in do_aspawn() (it was always invoking shell, instead of almost never) - implement and export win32_wait() - stub version of USE_RTL_THREAD_API p4raw-id: //depot/win32/perl@391
Diffstat (limited to 'win32/win32thread.h')
-rw-r--r--win32/win32thread.h45
1 files changed, 43 insertions, 2 deletions
diff --git a/win32/win32thread.h b/win32/win32thread.h
index 1a16c78b67..acb136c690 100644
--- a/win32/win32thread.h
+++ b/win32/win32thread.h
@@ -100,8 +100,39 @@ typedef HANDLE perl_mutex;
#define THREAD_CREATE(t, f) Perl_thread_create(t, f)
#define THREAD_POST_CREATE(t) NOOP
-#define THREAD_RET_TYPE DWORD WINAPI
-#define THREAD_RET_CAST(p) ((DWORD)(p))
+
+/* XXX Docs mention that the RTL versions of thread creation routines
+ * should be used, but that advice only seems applicable when the RTL
+ * is not in a DLL. RTL DLLs in both Borland and VC seem to do all of
+ * the init/deinit required upon DLL_THREAD_ATTACH/DETACH. So we seem
+ * to be completely safe using straight Win32 API calls, rather than
+ * the much braindamaged RTL calls.
+ *
+ * _beginthread() in the RTLs call CloseHandle() just after the thread
+ * function returns, which means: 1) we have a race on our hands
+ * 2) it is impossible to implement join() semantics.
+ *
+ * IOW, do *NOT* turn on USE_RTL_THREAD_API! It is here
+ * for experimental purposes only. GSAR 98-01-02
+ */
+#ifdef USE_RTL_THREAD_API
+# include <process.h>
+# if defined(__BORLANDC__)
+ /* Borland RTL doesn't allow a return value from thread function! */
+# define THREAD_RET_TYPE void _USERENTRY
+# define THREAD_RET_CAST(p) ((void)(thr->i.retv = (void *)(p)))
+# elif defined (_MSC_VER)
+# define THREAD_RET_TYPE unsigned __stdcall
+# define THREAD_RET_CAST(p) ((unsigned)(p))
+# else
+ /* CRTDLL.DLL doesn't allow a return value from thread function! */
+# define THREAD_RET_TYPE void __cdecl
+# define THREAD_RET_CAST(p) ((void)(thr->i.retv = (void *)(p)))
+# endif
+#else /* !USE_RTL_THREAD_API */
+# define THREAD_RET_TYPE DWORD WINAPI
+# define THREAD_RET_CAST(p) ((DWORD)(p))
+#endif /* !USE_RTL_THREAD_API */
typedef THREAD_RET_TYPE thread_func_t(void *);
@@ -131,12 +162,22 @@ END_EXTERN_C
#define ALLOC_THREAD_KEY Perl_alloc_thread_key()
#define SET_THREAD_SELF(thr) Perl_set_thread_self(thr)
+#if defined(USE_RTL_THREAD_API) && !defined(_MSC_VER)
+#define JOIN(t, avp) \
+ STMT_START { \
+ if ((WaitForSingleObject((t)->self,INFINITE) == WAIT_FAILED) \
+ || (GetExitCodeThread((t)->self,(LPDWORD)(avp)) == 0)) \
+ croak("panic: JOIN"); \
+ *avp = (AV *)((t)->i.retv); \
+ } STMT_END
+#else /* !USE_RTL_THREAD_API || _MSC_VER */
#define JOIN(t, avp) \
STMT_START { \
if ((WaitForSingleObject((t)->self,INFINITE) == WAIT_FAILED) \
|| (GetExitCodeThread((t)->self,(LPDWORD)(avp)) == 0)) \
croak("panic: JOIN"); \
} STMT_END
+#endif /* !USE_RTL_THREAD_API || _MSC_VER */
#define YIELD Sleep(0)