Mercurial > hg > octave-nkf > gnulib-hg
changeset 15784:f1e8251b45f3
msvc-inval: Install handler globally.
* lib/msvc-inval.h (STATUS_GNULIB_INVALID_PARAMETER): Define also for
!_MSC_VER.
(gl_msvc_invalid_parameter_handler): Remove declaration.
(gl_msvc_inval_restart_valid, gl_msvc_inval_ensure_handler): New
declarations.
(TRY_MSVC_INVAL, CATCH_MSVC_INVAL, DONE_MSVC_INVAL) [!_MSC_VER]:
Install the handler globally, don't uninstall it.
* lib/msvc-inval.c (gl_msvc_inval_restart_valid): New variable.
(gl_msvc_invalid_parameter_handler): Make static. If the restart is not
currently valid, call RaiseException instead.
(gl_msvc_inval_initialized, gl_msvc_inval_ensure_handler): Define also
for !_MSC_VER.
author | Bruno Haible <bruno@clisp.org> |
---|---|
date | Sun, 25 Sep 2011 21:05:20 +0200 |
parents | 4b59b93e3c12 |
children | 5e020d269ce6 |
files | ChangeLog lib/msvc-inval.c lib/msvc-inval.h |
diffstat | 3 files changed, 67 insertions(+), 47 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2011-09-25 Bruno Haible <bruno@clisp.org> + + msvc-inval: Install handler globally. + * lib/msvc-inval.h (STATUS_GNULIB_INVALID_PARAMETER): Define also for + !_MSC_VER. + (gl_msvc_invalid_parameter_handler): Remove declaration. + (gl_msvc_inval_restart_valid, gl_msvc_inval_ensure_handler): New + declarations. + (TRY_MSVC_INVAL, CATCH_MSVC_INVAL, DONE_MSVC_INVAL) [!_MSC_VER]: + Install the handler globally, don't uninstall it. + * lib/msvc-inval.c (gl_msvc_inval_restart_valid): New variable. + (gl_msvc_invalid_parameter_handler): Make static. If the restart is not + currently valid, call RaiseException instead. + (gl_msvc_inval_initialized, gl_msvc_inval_ensure_handler): Define also + for !_MSC_VER. + 2011-09-25 Bruno Haible <bruno@clisp.org> strerror_r-posix: Fix for MSVC 9.
--- a/lib/msvc-inval.c +++ b/lib/msvc-inval.c @@ -22,11 +22,11 @@ #if HAVE_MSVC_INVALID_PARAMETER_HANDLER -# ifdef STATUS_GNULIB_INVALID_PARAMETER +/* Get declarations of the Win32 API functions. */ +# define WIN32_LEAN_AND_MEAN +# include <windows.h> -/* Get declarations of the Win32 API functions. */ -# define WIN32_LEAN_AND_MEAN -# include <windows.h> +# if defined _MSC_VER static void cdecl gl_msvc_invalid_parameter_handler (const wchar_t *expression, @@ -38,6 +38,28 @@ RaiseException (STATUS_GNULIB_INVALID_PARAMETER, 0, 0, NULL); } +# else + +jmp_buf gl_msvc_inval_restart; +int gl_msvc_inval_restart_valid; + +static void cdecl +gl_msvc_invalid_parameter_handler (const wchar_t *expression, + const wchar_t *function, + const wchar_t *file, + unsigned int line, + uintptr_t dummy) +{ + if (gl_msvc_inval_restart_valid) + longjmp (gl_msvc_inval_restart, 1); + else + /* An invalid parameter notification from outside the gnulib code. + Give the caller a chance to intervene. */ + RaiseException (STATUS_GNULIB_INVALID_PARAMETER, 0, 0, NULL); +} + +# endif + static int gl_msvc_inval_initialized /* = 0 */; void @@ -50,20 +72,4 @@ } } -# else - -jmp_buf gl_msvc_inval_restart; - -void cdecl -gl_msvc_invalid_parameter_handler (const wchar_t *expression, - const wchar_t *function, - const wchar_t *file, - unsigned int line, - uintptr_t dummy) -{ - longjmp (gl_msvc_inval_restart, 1); -} - -# endif - #endif
--- a/lib/msvc-inval.h +++ b/lib/msvc-inval.h @@ -47,14 +47,7 @@ /* Get _invalid_parameter_handler type and _set_invalid_parameter_handler declaration. */ # include <stdlib.h> - -# if defined _MSC_VER -/* A compiler that supports __try/__except, as described in the page - "try-except statement" on microsoft.com - <http://msdn.microsoft.com/en-us/library/s58ftw19.aspx>. - With __try/__except, we can use the multithread-safe exception handling. */ - -# include <excpt.h> +# include <excpt.h> /* Gnulib can define its own status codes, as described in the page "Raising Software Exceptions" on microsoft.com @@ -64,7 +57,13 @@ - 0x474E550, a API identifier ("GNU"), - 0, 1, 2, ..., used to distinguish different status codes from the same API. */ -# define STATUS_GNULIB_INVALID_PARAMETER (0xE0000000 + 0x474E550 + 0) +# define STATUS_GNULIB_INVALID_PARAMETER (0xE0000000 + 0x474E550 + 0) + +# if defined _MSC_VER +/* A compiler that supports __try/__except, as described in the page + "try-except statement" on microsoft.com + <http://msdn.microsoft.com/en-us/library/s58ftw19.aspx>. + With __try/__except, we can use the multithread-safe exception handling. */ # ifdef __cplusplus extern "C" { @@ -95,8 +94,7 @@ # else /* Any compiler. - We can only use setjmp/longjmp. - Unfortunately, this is *not* multithread-safe. */ + We can only use setjmp/longjmp. */ # include <setjmp.h> @@ -109,14 +107,15 @@ TRY_MSVC_INVAL and CATCH_MSVC_INVAL. */ extern jmp_buf gl_msvc_inval_restart; -/* The invalid parameter handler that unwinds the stack up to the - gl_msvc_inval_restart. It is enabled only between TRY_MSVC_INVAL - and CATCH_MSVC_INVAL. */ -extern void cdecl gl_msvc_invalid_parameter_handler (const wchar_t *expression, - const wchar_t *function, - const wchar_t *file, - unsigned int line, - uintptr_t dummy); +/* Tells whether the contents of gl_msvc_inval_restart is valid. */ +extern int gl_msvc_inval_restart_valid; + +/* Ensure that the invalid parameter handler in installed that passes + control to the gl_msvc_inval_restart if it is valid, or raises a + software exception with code STATUS_GNULIB_INVALID_PARAMETER otherwise. + Because we assume no other part of the program installs a different + invalid parameter handler, this solution is multithread-safe. */ +extern void gl_msvc_inval_ensure_handler (void); # ifdef __cplusplus } @@ -125,23 +124,22 @@ # define TRY_MSVC_INVAL \ do \ { \ - _invalid_parameter_handler orig_handler; \ + gl_msvc_inval_ensure_handler (); \ /* First, initialize gl_msvc_inval_restart. */ \ if (setjmp (gl_msvc_inval_restart) == 0) \ { \ - /* Then, enable gl_msvc_invalid_parameter_handler. */ \ - orig_handler = \ - _set_invalid_parameter_handler (gl_msvc_invalid_parameter_handler); + /* Then, mark it as valid. */ \ + gl_msvc_inval_restart_valid = 1; # define CATCH_MSVC_INVAL \ /* Execution completed. \ - Disable gl_msvc_invalid_parameter_handler. */ \ - _set_invalid_parameter_handler (orig_handler); \ + Mark gl_msvc_inval_restart as invalid. */ \ + gl_msvc_inval_restart_valid = 0; \ } \ else \ { \ /* Execution triggered an invalid parameter notification. \ - Disable gl_msvc_invalid_parameter_handler. */ \ - _set_invalid_parameter_handler (orig_handler); + Mark gl_msvc_inval_restart as invalid. */ \ + gl_msvc_inval_restart_valid = 0; # define DONE_MSVC_INVAL \ } \ } \