Raise an exception when a critical section wait failed.
diff --git a/debugger/dbg.y b/debugger/dbg.y
index e6f453d..96c6c7b 100644
--- a/debugger/dbg.y
+++ b/debugger/dbg.y
@@ -693,6 +693,9 @@
case CONTROL_C_EXIT:
fprintf( stderr, "^C" );
break;
+ case EXCEPTION_CRITICAL_SECTION_WAIT:
+ fprintf( stderr, "critical section %08lx wait failed", rec->ExceptionInformation[0] );
+ break;
default:
fprintf( stderr, "%08lx", rec->ExceptionCode );
break;
diff --git a/include/winbase.h b/include/winbase.h
index 7a21b01..69a656f 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -973,6 +973,8 @@
#define EXCEPTION_INVALID_HANDLE STATUS_INVALID_HANDLE
#define CONTROL_C_EXIT STATUS_CONTROL_C_EXIT
+/* Wine extension; Windows doesn't have a name for this code */
+#define EXCEPTION_CRITICAL_SECTION_WAIT 0xc0000194
#define DUPLICATE_CLOSE_SOURCE 0x00000001
#define DUPLICATE_SAME_ACCESS 0x00000002
diff --git a/scheduler/critsection.c b/scheduler/critsection.c
index 1f46cdb..d6e666a 100644
--- a/scheduler/critsection.c
+++ b/scheduler/critsection.c
@@ -10,6 +10,7 @@
#include <sys/types.h>
#include "winerror.h"
#include "winbase.h"
+#include "ntddk.h"
#include "heap.h"
#include "debugtools.h"
#include "thread.h"
@@ -78,21 +79,30 @@
}
/* Now wait for it */
- res = WaitForSingleObject( crit->LockSemaphore, 5000L );
- if ( res == WAIT_TIMEOUT )
+ for (;;)
{
- ERR_(win32)("Critical section %p wait timed out, retrying (60 sec)\n", crit );
- res = WaitForSingleObject( crit->LockSemaphore, 60000L );
- }
- if ( res == WAIT_TIMEOUT && TRACE_ON(relay) )
- {
- ERR_(win32)("Critical section %p wait timed out, retrying (5 min)\n", crit );
- res = WaitForSingleObject( crit->LockSemaphore, 300000L );
- }
- if (res != STATUS_WAIT_0)
- {
- ERR_(win32)("Critical section %p wait failed err=%lx\n", crit, res );
- /* FIXME: should raise an exception */
+ EXCEPTION_RECORD rec;
+
+ res = WaitForSingleObject( crit->LockSemaphore, 5000L );
+ if ( res == WAIT_TIMEOUT )
+ {
+ ERR_(win32)("Critical section %p wait timed out, retrying (60 sec)\n", crit );
+ res = WaitForSingleObject( crit->LockSemaphore, 60000L );
+ if ( res == WAIT_TIMEOUT && TRACE_ON(relay) )
+ {
+ ERR_(win32)("Critical section %p wait timed out, retrying (5 min)\n", crit );
+ res = WaitForSingleObject( crit->LockSemaphore, 300000L );
+ }
+ }
+ if (res == STATUS_WAIT_0) break;
+
+ rec.ExceptionCode = EXCEPTION_CRITICAL_SECTION_WAIT;
+ rec.ExceptionFlags = 0;
+ rec.ExceptionRecord = NULL;
+ rec.ExceptionAddress = RtlRaiseException; /* sic */
+ rec.NumberParameters = 1;
+ rec.ExceptionInformation[0] = (DWORD)crit;
+ RtlRaiseException( &rec );
}
}
crit->OwningThread = GetCurrentThreadId();