diff options
author | Christopher Faylor <me@cgf.cx> | 2010-02-26 21:36:31 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2010-02-26 21:36:31 +0000 |
commit | d5d5bf4dd5609dd29e511d688e317b2f0f1987ca (patch) | |
tree | 01fa2b080346cfda5b393bc54c0ab387524c2f33 /winsup/cygwin/cygtls.h | |
parent | b6336c95b4c1d512d4cb139e7b97ec4d1ef843fc (diff) | |
download | newlib-d5d5bf4dd5609dd29e511d688e317b2f0f1987ca.zip newlib-d5d5bf4dd5609dd29e511d688e317b2f0f1987ca.tar.gz newlib-d5d5bf4dd5609dd29e511d688e317b2f0f1987ca.tar.bz2 |
* cygtls.h (_cygtls::init_exception_handler): Eliminate argument.
(_cygtls::andreas): Convert to a pointer.
(san): Convert to a real class with methods. Use a linked list to keep track
of previous handlers on the "stack".
(myfault): Rewrite to use new san class rather than calling directly into
_cygtls.
* cygtls.cc (_cygtls::init_exception_handler): Just assume that we're always
using the standard exception handler.
(_cygtls::init_thread): Reflect loss of argument to init_exception_handler.
* dcrt0.cc (dll_crt0_1): Ditto.
* dfcn.cc (dlopen): Ditto.
(dlclose): Reset the exception handler after FreeLibrary.
* dll_init.cc (dll_list::detach): Make sure that the exception handler is
initialized before calling destructors.
* exceptions.cc (_cygtls::handle_exceptions): Accommodate new andreas pointer.
* thread.cc (verifyable_object_isvalid): Pass objectptr to faulted for explicit
NULL pointer checking.
* tlsoffsets.h: Regenerate.
Diffstat (limited to 'winsup/cygwin/cygtls.h')
-rw-r--r-- | winsup/cygwin/cygtls.h | 88 |
1 files changed, 46 insertions, 42 deletions
diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h index f05379f..489e809 100644 --- a/winsup/cygwin/cygtls.h +++ b/winsup/cygwin/cygtls.h @@ -53,6 +53,7 @@ public: void destroy (); friend class tmp_pathbuf; friend class _cygtls; + friend class san; }; class unionent @@ -157,14 +158,6 @@ typedef struct struct_waitq HANDLE thread_ev; } waitq; -typedef struct -{ - void *_myfault; - int _myfault_errno; - int _myfault_c_cnt; - int _myfault_w_cnt; -} san; - /* Changes to the below structure may require acompanying changes to the very simple parser in the perl script 'gentls_offsets' (<<-- start parsing here). The union in this structure is used to force alignment between the version @@ -205,7 +198,7 @@ struct _cygtls }; struct _local_storage locals; class cygthread *_ctinfo; - san andreas; + class san *andreas; waitq wq; int sig; unsigned incyg; @@ -239,7 +232,7 @@ struct _cygtls /* exception handling */ static int handle_exceptions (EXCEPTION_RECORD *, exception_list *, CONTEXT *, void *); bool inside_kernel (CONTEXT *); - void init_exception_handler (int (*) (EXCEPTION_RECORD *, exception_list *, CONTEXT *, void*)); + void init_exception_handler () __attribute__ ((regparm(1))); void signal_exit (int) __attribute__ ((noreturn, regparm(2))); void copy_context (CONTEXT *) __attribute__ ((regparm(2))); void signal_debugger (int) __attribute__ ((regparm(2))); @@ -256,34 +249,6 @@ struct _cygtls void lock () __attribute__ ((regparm (1))); void unlock () __attribute__ ((regparm (1))); bool locked () __attribute__ ((regparm (1))); - void*& fault_guarded () {return andreas._myfault;} - void return_from_fault () - { - if (andreas._myfault_errno) - set_errno (andreas._myfault_errno); - /* Restore tls_pathbuf counters in case of error. */ - locals.pathbufs.c_cnt = andreas._myfault_c_cnt; - locals.pathbufs.w_cnt = andreas._myfault_w_cnt; - __ljfault ((int *) andreas._myfault, 1); - } - int setup_fault (jmp_buf j, san& old_j, int myerrno) __attribute__ ((always_inline)) - { - old_j._myfault = andreas._myfault; - old_j._myfault_errno = andreas._myfault_errno; - old_j._myfault_c_cnt = andreas._myfault_c_cnt; - old_j._myfault_w_cnt = andreas._myfault_w_cnt; - andreas._myfault = (void *) j; - andreas._myfault_errno = myerrno; - /* Save tls_pathbuf counters. */ - andreas._myfault_c_cnt = locals.pathbufs.c_cnt; - andreas._myfault_w_cnt = locals.pathbufs.w_cnt; - return __sjfault (j); - } - void reset_fault (san& old_j) __attribute__ ((always_inline)) - { - andreas._myfault = old_j._myfault; - andreas._myfault_errno = old_j._myfault_errno; - } /*gentls_offsets*/ }; #pragma pack(pop) @@ -298,15 +263,54 @@ extern char *_tlstop __asm__ ("%fs:8"); extern _cygtls *_main_tls; extern _cygtls *_sig_tls; +class san +{ + san *_clemente; + jmp_buf _context; + int _errno; + int _c_cnt; + int _w_cnt; +public: + int setup (int myerrno = 0) __attribute__ ((always_inline)) + { + _clemente = _my_tls.andreas; + _my_tls.andreas = this; + _errno = myerrno; + _c_cnt = _my_tls.locals.pathbufs.c_cnt; + _w_cnt = _my_tls.locals.pathbufs.w_cnt; + return __sjfault (_context); + } + void leave () __attribute__ ((always_inline)) + { + if (_errno) + set_errno (_errno); + /* Restore tls_pathbuf counters in case of error. */ + _my_tls.locals.pathbufs.c_cnt = _c_cnt; + _my_tls.locals.pathbufs.w_cnt = _w_cnt; + __ljfault (_context, 1); + } + void reset () __attribute__ ((always_inline)) + { + _my_tls.andreas = _clemente; + } +}; + class myfault { - jmp_buf buf; san sebastian; public: - ~myfault () __attribute__ ((always_inline)) { _my_tls.reset_fault (sebastian); } - inline int faulted (int myerrno = 0) __attribute__ ((always_inline)) + ~myfault () __attribute__ ((always_inline)) { sebastian.reset (); } + inline int faulted () __attribute__ ((always_inline)) + { + return sebastian.setup (0); + } + inline int faulted (void const *obj, int myerrno = 0) __attribute__ ((always_inline)) + { + return (!obj || !(*(const char **)obj)) || sebastian.setup (myerrno); + } + inline int faulted (int myerrno) __attribute__ ((always_inline)) { - return _my_tls.setup_fault (buf, sebastian, myerrno); + return sebastian.setup (myerrno); } }; |