summaryrefslogtreecommitdiffstats
path: root/win/tclWinThrd.c
diff options
context:
space:
mode:
authorJoe Mistachkin <joe@mistachkin.com>2012-09-13 18:30:41 (GMT)
committerJoe Mistachkin <joe@mistachkin.com>2012-09-13 18:30:41 (GMT)
commit77806ded9e45e9569f778847e63516f884788da2 (patch)
tree7cdfe38474fe77bdd431d70c3ccdcb8767e64cbd /win/tclWinThrd.c
parent087231e55e5ff1f00a7c61f88faac65f8155f504 (diff)
downloadtcl-77806ded9e45e9569f778847e63516f884788da2.zip
tcl-77806ded9e45e9569f778847e63516f884788da2.tar.gz
tcl-77806ded9e45e9569f778847e63516f884788da2.tar.bz2
Initial work on SF FRQ #3567063.
Diffstat (limited to 'win/tclWinThrd.c')
-rw-r--r--win/tclWinThrd.c60
1 files changed, 56 insertions, 4 deletions
diff --git a/win/tclWinThrd.c b/win/tclWinThrd.c
index 13fd411..7abcc29 100644
--- a/win/tclWinThrd.c
+++ b/win/tclWinThrd.c
@@ -13,6 +13,7 @@
#include "tclWinInt.h"
#include <fcntl.h>
+#include <float.h>
#include <io.h>
#include <sys/stat.h>
@@ -122,6 +123,52 @@ typedef struct WinCondition {
struct ThreadSpecificData *lastPtr;
} WinCondition;
+/*
+ * The per thread data passed from TclpThreadCreate
+ * to TclWinThreadStart.
+ */
+
+typedef struct WinThread {
+ LPTHREAD_START_ROUTINE lpStartAddress; /* Original startup routine */
+ LPVOID lpParameter; /* Original startup data */
+ unsigned int fpControl; /* Floating point control word from the
+ * main thread */
+} WinThread;
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclWinThreadStart --
+ *
+ * This procedure is the entry point for all new threads created
+ * by Tcl on Windows.
+ *
+ * Results:
+ * Various, depending on the result of the wrapped thread start
+ * routine.
+ *
+ * Side effects:
+ * Arbitrary, since user code is executed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static DWORD WINAPI
+TclWinThreadStart(
+ LPVOID lpParameter) /* The WinThread structure pointer passed
+ * from TclpThreadCreate */
+{
+ WinThread *winThreadPtr = (WinThread *) lpParameter;
+ unsigned int fpmask = _MCW_EM | _MCW_RC | _MCW_PC | _MCW_DN;
+
+ if (!winThreadPtr) {
+ return TCL_ERROR;
+ }
+
+ _controlfp(winThreadPtr->fpControl, fpmask);
+ return winThreadPtr->lpStartAddress(winThreadPtr->lpParameter);
+}
/*
*----------------------------------------------------------------------
@@ -149,17 +196,22 @@ TclpThreadCreate(idPtr, proc, clientData, stackSize, flags)
int flags; /* Flags controlling behaviour of
* the new thread */
{
+ WinThread *winThreadPtr; /* Per-thread startup info */
HANDLE tHandle;
+ winThreadPtr = (WinThread *)ckalloc(sizeof(WinThread));
+ winThreadPtr->lpStartAddress = proc;
+ winThreadPtr->lpParameter = clientData;
+ winThreadPtr->fpControl = _controlfp(0, 0);
+
EnterCriticalSection(&joinLock);
#if defined(_MSC_VER) || defined(__MSVCRT__) || defined(__BORLANDC__)
- tHandle = (HANDLE) _beginthreadex(NULL, (unsigned) stackSize, proc,
- clientData, 0, (unsigned *)idPtr);
+ tHandle = (HANDLE) _beginthreadex(NULL, (unsigned) stackSize,
+ TclWinThreadStart, winThreadPtr, 0, (unsigned *)idPtr);
#else
tHandle = CreateThread(NULL, (DWORD) stackSize,
- (LPTHREAD_START_ROUTINE) proc, (LPVOID) clientData,
- (DWORD) 0, (LPDWORD)idPtr);
+ TclWinThreadStart, winThreadPtr, 0, (LPDWORD)idPtr);
#endif
if (tHandle == NULL) {