From 911b42b27ad5f039465d14052460e2d9dde053ab Mon Sep 17 00:00:00 2001 From: Simon Marlow Date: Fri, 26 Jan 2007 16:26:20 +0000 Subject: [PATCH] Save the Win32 error code where necessary Similarly to the way we save errno across context switches and suspendThread/resumeThread, we must save and restore the Win32 error code via GetLastError()/SetLastError(). Fixes #896. --- includes/TSO.h | 3 +++ rts/Schedule.c | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/includes/TSO.h b/includes/TSO.h index 3f7923d..088097e 100644 --- a/includes/TSO.h +++ b/includes/TSO.h @@ -159,6 +159,9 @@ typedef struct StgTSO_ { #ifdef DIST StgTSODistInfo dist; #endif +#ifdef mingw32_HOST_OS + StgWord32 saved_winerror; +#endif /* The thread stack... */ StgWord32 stack_size; /* stack size in *words* */ diff --git a/rts/Schedule.c b/rts/Schedule.c index c068919..a7a0f33 100644 --- a/rts/Schedule.c +++ b/rts/Schedule.c @@ -588,6 +588,10 @@ run_thread: prev_what_next = t->what_next; errno = t->saved_errno; +#if mingw32_HOST_OS + SetLastError(t->saved_winerror); +#endif + cap->in_haskell = rtsTrue; dirtyTSO(t); @@ -637,6 +641,10 @@ run_thread: // XXX: possibly bogus for SMP because this thread might already // be running again, see code below. t->saved_errno = errno; +#if mingw32_HOST_OS + // Similarly for Windows error code + SetLastError(t->saved_winerror); +#endif #if defined(THREADED_RTS) // If ret is ThreadBlocked, and this Task is bound to the TSO that @@ -2283,9 +2291,17 @@ void * suspendThread (StgRegTable *reg) { Capability *cap; - int saved_errno = errno; + int saved_errno; StgTSO *tso; Task *task; +#if mingw32_HOST_OS + StgWord32 saved_winerror; +#endif + + saved_errno = errno; +#if mingw32_HOST_OS + saved_winerror = GetLastError(); +#endif /* assume that *reg is a pointer to the StgRegTable part of a Capability. */ @@ -2330,6 +2346,9 @@ suspendThread (StgRegTable *reg) #endif errno = saved_errno; +#if mingw32_HOST_OS + SetLastError(saved_winerror); +#endif return task; } @@ -2338,8 +2357,16 @@ resumeThread (void *task_) { StgTSO *tso; Capability *cap; - int saved_errno = errno; Task *task = task_; + int saved_errno; +#if mingw32_HOST_OS + StgWord32 saved_winerror; +#endif + + saved_errno = errno; +#if mingw32_HOST_OS + saved_winerror = GetLastError(); +#endif cap = task->cap; // Wait for permission to re-enter the RTS with the result. @@ -2367,6 +2394,9 @@ resumeThread (void *task_) cap->r.rCurrentTSO = tso; cap->in_haskell = rtsTrue; errno = saved_errno; +#if mingw32_HOST_OS + SetLastError(saved_winerror); +#endif /* We might have GC'd, mark the TSO dirty again */ dirtyTSO(tso); -- 1.7.10.4