2003-11-29 04:55:59 +08:00
|
|
|
/* cygtls.h
|
|
|
|
|
|
|
|
This software is a copyrighted work licensed under the terms of the
|
|
|
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
|
|
|
details. */
|
|
|
|
|
2012-07-22 06:58:20 +08:00
|
|
|
#pragma once
|
2003-11-29 04:55:59 +08:00
|
|
|
|
2003-12-24 00:26:31 +08:00
|
|
|
#include <signal.h>
|
|
|
|
#include <pwd.h>
|
|
|
|
#include <grp.h>
|
2009-01-03 13:12:22 +08:00
|
|
|
#include <time.h>
|
2003-12-24 00:26:31 +08:00
|
|
|
#define _NOMNTENT_FUNCS
|
|
|
|
#include <mntent.h>
|
|
|
|
#undef _NOMNTENT_FUNCS
|
2005-07-03 10:40:30 +08:00
|
|
|
#include <setjmp.h>
|
2015-07-05 04:49:30 +08:00
|
|
|
#include <ucontext.h>
|
2003-11-29 04:55:59 +08:00
|
|
|
|
2006-03-13 07:57:05 +08:00
|
|
|
#define CYGTLS_INITIALIZED 0xc763173f
|
2003-11-29 04:55:59 +08:00
|
|
|
|
2003-12-24 00:26:31 +08:00
|
|
|
#ifndef CYG_MAX_PATH
|
|
|
|
# define CYG_MAX_PATH 260
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef UNLEN
|
|
|
|
# define UNLEN 256
|
|
|
|
#endif
|
|
|
|
|
2004-01-14 23:45:37 +08:00
|
|
|
#define TLS_STACK_SIZE 256
|
2004-01-04 02:15:03 +08:00
|
|
|
|
2004-11-26 12:15:10 +08:00
|
|
|
#include "cygthread.h"
|
|
|
|
|
2014-04-18 22:29:49 +08:00
|
|
|
#define TP_NUM_C_BUFS 50
|
|
|
|
#define TP_NUM_W_BUFS 50
|
2008-03-07 19:24:51 +08:00
|
|
|
|
2009-01-03 13:12:22 +08:00
|
|
|
#ifdef CYGTLS_HANDLE
|
|
|
|
#include "thread.h"
|
|
|
|
#endif
|
|
|
|
|
2013-04-23 17:44:36 +08:00
|
|
|
#pragma pack(push,8)
|
2014-08-22 17:21:33 +08:00
|
|
|
|
2008-03-07 19:24:51 +08:00
|
|
|
/* Defined here to support auto rebuild of tlsoffsets.h. */
|
|
|
|
class tls_pathbuf
|
|
|
|
{
|
2014-08-22 17:21:33 +08:00
|
|
|
/* Make sure that c_cnt and w_cnt are always the first two members of this
|
|
|
|
class, and never change the size (32 bit), unless you also change the
|
|
|
|
mov statements in sigbe! */
|
2014-08-26 03:47:44 +08:00
|
|
|
union
|
|
|
|
{
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
uint32_t c_cnt;
|
|
|
|
uint32_t w_cnt;
|
|
|
|
};
|
|
|
|
uint64_t _counters;
|
|
|
|
};
|
Cygwin: tls_pathbuf: Use Windows heap
Rather than using malloc/free for the buffers, we're now using
HeapAlloc/HeapFree on a HEAP_NO_SERIALIZE heap created for this
thread.
Advantages:
- Less contention. Our malloc/free doesn't scale well in
multithreaded scenarios
- Even faster heap allocation by using a non serialized heap.
- Internal, local, temporary data not cluttering the user heap.
- Internal, local, temporary data not copied over to child process
at fork().
Disadvantage:
- A forked process has to start allocating temporary buffers from
scratch. However, this should be alleviated by the fact that
buffer allocation usually reaches its peak very early in process
runtime, so the longer the proceess runs, the less buffers have
to allocated, and, only few processes don't exec after fork
anyway.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2022-08-23 16:59:18 +08:00
|
|
|
HANDLE tls_heap;
|
2008-03-07 19:24:51 +08:00
|
|
|
char *c_buf[TP_NUM_C_BUFS];
|
|
|
|
WCHAR *w_buf[TP_NUM_W_BUFS];
|
|
|
|
|
|
|
|
public:
|
Cygwin: tls_pathbuf: Use Windows heap
Rather than using malloc/free for the buffers, we're now using
HeapAlloc/HeapFree on a HEAP_NO_SERIALIZE heap created for this
thread.
Advantages:
- Less contention. Our malloc/free doesn't scale well in
multithreaded scenarios
- Even faster heap allocation by using a non serialized heap.
- Internal, local, temporary data not cluttering the user heap.
- Internal, local, temporary data not copied over to child process
at fork().
Disadvantage:
- A forked process has to start allocating temporary buffers from
scratch. However, this should be alleviated by the fact that
buffer allocation usually reaches its peak very early in process
runtime, so the longer the proceess runs, the less buffers have
to allocated, and, only few processes don't exec after fork
anyway.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2022-08-23 16:59:18 +08:00
|
|
|
void clear () { memset (this, 0, sizeof *this); }
|
|
|
|
void create ();
|
2008-03-07 19:24:51 +08:00
|
|
|
void destroy ();
|
|
|
|
friend class tmp_pathbuf;
|
2010-02-27 05:36:31 +08:00
|
|
|
friend class san;
|
2008-03-07 19:24:51 +08:00
|
|
|
};
|
|
|
|
|
2008-09-16 10:04:27 +08:00
|
|
|
class unionent
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
char *name;
|
|
|
|
char **list;
|
|
|
|
short port_proto_addrtype;
|
|
|
|
short h_len;
|
|
|
|
union
|
|
|
|
{
|
|
|
|
char *s_proto;
|
|
|
|
char **h_addr_list;
|
|
|
|
};
|
|
|
|
enum struct_type
|
|
|
|
{
|
|
|
|
t_hostent, t_protoent, t_servent
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2003-12-24 00:26:31 +08:00
|
|
|
struct _local_storage
|
|
|
|
{
|
2014-02-10 03:44:56 +08:00
|
|
|
/* passwd.cc */
|
|
|
|
char pass[_PASSWORD_LEN];
|
|
|
|
|
2003-12-24 00:26:31 +08:00
|
|
|
/* dlfcn.cc */
|
|
|
|
int dl_error;
|
|
|
|
char dl_buffer[256];
|
|
|
|
|
|
|
|
/* path.cc */
|
|
|
|
struct mntent mntbuf;
|
|
|
|
int iteration;
|
|
|
|
unsigned available_drives;
|
|
|
|
char mnt_type[80];
|
|
|
|
char mnt_opts[80];
|
|
|
|
char mnt_fsname[CYG_MAX_PATH];
|
|
|
|
char mnt_dir[CYG_MAX_PATH];
|
|
|
|
|
2004-10-11 10:21:31 +08:00
|
|
|
/* select.cc */
|
2009-07-06 23:42:01 +08:00
|
|
|
struct {
|
|
|
|
HANDLE sockevt;
|
|
|
|
int max_w4;
|
|
|
|
LONG *ser_num; // note: malloced
|
|
|
|
HANDLE *w4; // note: malloced
|
|
|
|
} select;
|
2004-10-11 10:21:31 +08:00
|
|
|
|
2011-05-24 05:03:06 +08:00
|
|
|
/* strerror errno.cc */
|
|
|
|
char strerror_buf[sizeof ("Unknown error -2147483648")];
|
2011-05-26 02:47:32 +08:00
|
|
|
char strerror_r_buf[sizeof ("Unknown error -2147483648")];
|
2003-12-24 00:26:31 +08:00
|
|
|
|
|
|
|
/* times.cc */
|
|
|
|
char timezone_buf[20];
|
|
|
|
|
2011-05-16 23:12:35 +08:00
|
|
|
/* strsig.cc */
|
|
|
|
char signamebuf[sizeof ("Unknown signal 4294967295 ")];
|
2003-12-24 00:26:31 +08:00
|
|
|
|
|
|
|
/* net.cc */
|
2005-03-17 01:07:32 +08:00
|
|
|
char *ntoa_buf; // note: malloced
|
2008-09-16 10:04:27 +08:00
|
|
|
unionent *hostent_buf; // note: malloced
|
|
|
|
unionent *protoent_buf; // note: malloced
|
|
|
|
unionent *servent_buf; // note: malloced
|
|
|
|
|
2005-05-19 07:30:02 +08:00
|
|
|
/* cygthread.cc */
|
|
|
|
char unknown_thread_name[30];
|
2005-06-10 06:33:57 +08:00
|
|
|
|
|
|
|
/* syscalls.cc */
|
|
|
|
int setmode_file;
|
|
|
|
int setmode_mode;
|
2008-03-07 19:24:51 +08:00
|
|
|
|
2011-08-04 00:40:48 +08:00
|
|
|
/* thread.cc */
|
|
|
|
HANDLE cw_timer;
|
|
|
|
|
2014-08-25 22:53:49 +08:00
|
|
|
tls_pathbuf pathbufs;
|
2011-05-29 02:17:09 +08:00
|
|
|
char ttybuf[32];
|
2003-12-24 00:26:31 +08:00
|
|
|
};
|
|
|
|
|
2004-03-12 11:09:28 +08:00
|
|
|
typedef struct struct_waitq
|
|
|
|
{
|
|
|
|
int pid;
|
|
|
|
int options;
|
|
|
|
int status;
|
|
|
|
HANDLE ev;
|
|
|
|
void *rusage; /* pointer to potential rusage */
|
|
|
|
struct struct_waitq *next;
|
|
|
|
HANDLE thread_ev;
|
|
|
|
} waitq;
|
|
|
|
|
2022-02-03 00:27:34 +08:00
|
|
|
/* Changes to the below structure may require acompanying changes to the
|
|
|
|
gawk parser in the shell script 'gentls_offsets' */
|
2005-07-03 10:40:30 +08:00
|
|
|
|
|
|
|
extern "C" int __sjfault (jmp_buf);
|
2005-08-29 07:26:23 +08:00
|
|
|
extern "C" int __ljfault (jmp_buf, int);
|
|
|
|
|
2015-06-19 21:58:23 +08:00
|
|
|
typedef uintptr_t __tlsstack_t;
|
2010-02-28 23:54:25 +08:00
|
|
|
|
|
|
|
class _cygtls
|
2003-11-29 04:55:59 +08:00
|
|
|
{
|
2022-02-03 00:27:34 +08:00
|
|
|
public: /* Do NOT remove this public: line, it's a marker for gentls_offsets. */
|
|
|
|
/* offsetoff (class _cygtls, local_clib) *must* be 0. */
|
|
|
|
struct _reent local_clib;
|
2022-01-27 19:39:57 +08:00
|
|
|
struct _local_storage locals;
|
2012-07-22 06:58:20 +08:00
|
|
|
/**/
|
2022-02-03 00:27:34 +08:00
|
|
|
void (*func) (int, siginfo_t *, void *);
|
2003-11-29 04:55:59 +08:00
|
|
|
int saved_errno;
|
|
|
|
int sa_flags;
|
|
|
|
sigset_t oldmask;
|
2004-03-12 11:09:28 +08:00
|
|
|
sigset_t deltamask;
|
2003-11-29 04:55:59 +08:00
|
|
|
int *errno_addr;
|
|
|
|
sigset_t sigmask;
|
|
|
|
sigset_t sigwait_mask;
|
2015-06-19 21:58:23 +08:00
|
|
|
stack_t altstack;
|
2003-11-29 04:55:59 +08:00
|
|
|
siginfo_t *sigwait_info;
|
2012-07-22 06:58:20 +08:00
|
|
|
HANDLE signal_arrived;
|
2012-12-05 04:26:18 +08:00
|
|
|
bool will_wait_for_signal;
|
Cygwin: cygtls: fix context alignment
A hang was encountered, apparently triggered by commit 63b503916d42,
changing tls_pathbufs from malloc'ed to HeapAlloc'ed memory. After
lengthy debugging it transpired that adding the heap handle to the
tls_pathbuf struct added 8 bytes to the cygtls area, thus moving
the "context" member by 8 bytes, too, so it was suddently unaligned.
Fix this for now by changing the alignment.
Fix this once and for all, by adding code to the gentls_offsets script
to check if the alignment of the "context" member is 16 bytes. If not,
print a matching error message, remove the just generated file, and exit
with error.
FIXME: It would be really nice to find a way to auomate the correct
alignment of the "context" member, but I don't see any way to use
alignment attributes to get what we need here.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2022-08-29 21:18:53 +08:00
|
|
|
#if 0
|
2019-08-16 22:36:06 +08:00
|
|
|
long __align; /* Needed to align context to 16 byte. */
|
Cygwin: cygtls: fix context alignment
A hang was encountered, apparently triggered by commit 63b503916d42,
changing tls_pathbufs from malloc'ed to HeapAlloc'ed memory. After
lengthy debugging it transpired that adding the heap handle to the
tls_pathbuf struct added 8 bytes to the cygtls area, thus moving
the "context" member by 8 bytes, too, so it was suddently unaligned.
Fix this for now by changing the alignment.
Fix this once and for all, by adding code to the gentls_offsets script
to check if the alignment of the "context" member is 16 bytes. If not,
print a matching error message, remove the just generated file, and exit
with error.
FIXME: It would be really nice to find a way to auomate the correct
alignment of the "context" member, but I don't see any way to use
alignment attributes to get what we need here.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2022-08-29 21:18:53 +08:00
|
|
|
#endif
|
2019-01-15 00:19:37 +08:00
|
|
|
/* context MUST be aligned to 16 byte, otherwise RtlCaptureContext fails.
|
|
|
|
If you prepend cygtls members here, make sure context stays 16 byte
|
Cygwin: cygtls: fix context alignment
A hang was encountered, apparently triggered by commit 63b503916d42,
changing tls_pathbufs from malloc'ed to HeapAlloc'ed memory. After
lengthy debugging it transpired that adding the heap handle to the
tls_pathbuf struct added 8 bytes to the cygtls area, thus moving
the "context" member by 8 bytes, too, so it was suddently unaligned.
Fix this for now by changing the alignment.
Fix this once and for all, by adding code to the gentls_offsets script
to check if the alignment of the "context" member is 16 bytes. If not,
print a matching error message, remove the just generated file, and exit
with error.
FIXME: It would be really nice to find a way to auomate the correct
alignment of the "context" member, but I don't see any way to use
alignment attributes to get what we need here.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2022-08-29 21:18:53 +08:00
|
|
|
aligned. The gentls_offsets script checks for that now and fails
|
|
|
|
if the alignment is wrong. */
|
2022-09-06 01:49:11 +08:00
|
|
|
ucontext_t context;
|
2006-02-07 02:24:11 +08:00
|
|
|
DWORD thread_id;
|
2003-11-29 04:55:59 +08:00
|
|
|
siginfo_t infodata;
|
2003-11-29 08:26:40 +08:00
|
|
|
struct pthread *tid;
|
2004-11-26 12:15:10 +08:00
|
|
|
class cygthread *_ctinfo;
|
2010-02-27 05:36:31 +08:00
|
|
|
class san *andreas;
|
2004-03-12 11:09:28 +08:00
|
|
|
waitq wq;
|
2003-12-30 11:59:45 +08:00
|
|
|
int sig;
|
2004-03-07 12:57:47 +08:00
|
|
|
unsigned incyg;
|
2004-03-09 09:24:08 +08:00
|
|
|
unsigned spinning;
|
|
|
|
unsigned stacklock;
|
2015-06-19 21:58:23 +08:00
|
|
|
__tlsstack_t *stackptr;
|
|
|
|
__tlsstack_t stack[TLS_STACK_SIZE];
|
2006-03-13 12:26:57 +08:00
|
|
|
unsigned initialized;
|
2003-11-29 04:55:59 +08:00
|
|
|
|
2022-02-03 00:27:34 +08:00
|
|
|
public: /* Do NOT remove this public: line, it's a marker for gentls_offsets. */
|
2004-01-14 23:45:37 +08:00
|
|
|
void init_thread (void *, DWORD (*) (void *, void *));
|
|
|
|
static void call (DWORD (*) (void *, void *), void *);
|
|
|
|
void remove (DWORD);
|
2015-06-19 21:58:23 +08:00
|
|
|
void push (__tlsstack_t addr) {*stackptr++ = (__tlsstack_t) addr;}
|
2022-05-24 03:52:52 +08:00
|
|
|
__tlsstack_t pop ();
|
2015-06-19 21:58:23 +08:00
|
|
|
__tlsstack_t retaddr () {return stackptr[-1];}
|
2006-06-02 08:09:50 +08:00
|
|
|
bool isinitialized () const
|
|
|
|
{
|
2008-10-07 10:38:15 +08:00
|
|
|
return initialized == CYGTLS_INITIALIZED;
|
2006-06-02 08:09:50 +08:00
|
|
|
}
|
2022-05-24 03:52:52 +08:00
|
|
|
bool interrupt_now (CONTEXT *, siginfo_t&, void *, struct sigaction&);
|
|
|
|
void interrupt_setup (siginfo_t&, void *, struct sigaction&);
|
2005-12-03 12:23:35 +08:00
|
|
|
|
2007-07-29 13:22:05 +08:00
|
|
|
bool inside_kernel (CONTEXT *);
|
2022-05-24 03:52:52 +08:00
|
|
|
void signal_debugger (siginfo_t&);
|
2005-12-03 12:23:35 +08:00
|
|
|
|
2009-01-03 13:12:22 +08:00
|
|
|
#ifdef CYGTLS_HANDLE
|
2012-08-17 03:24:19 +08:00
|
|
|
operator HANDLE () const {return tid ? tid->win32_obj_id : NULL;}
|
2005-07-03 10:40:30 +08:00
|
|
|
#endif
|
2022-05-24 03:52:52 +08:00
|
|
|
int call_signal_handler ();
|
|
|
|
void remove_wq (DWORD);
|
|
|
|
void fixup_after_fork ();
|
|
|
|
void lock ();
|
|
|
|
void unlock ();
|
|
|
|
bool locked ();
|
2012-12-08 01:23:22 +08:00
|
|
|
HANDLE get_signal_arrived (bool wait_for_lock = true)
|
2012-08-16 02:50:44 +08:00
|
|
|
{
|
2012-12-05 04:26:18 +08:00
|
|
|
if (!signal_arrived)
|
|
|
|
{
|
2012-12-08 01:23:22 +08:00
|
|
|
if (wait_for_lock)
|
|
|
|
lock ();
|
2012-12-05 04:26:18 +08:00
|
|
|
if (!signal_arrived)
|
2013-04-23 17:44:36 +08:00
|
|
|
signal_arrived = CreateEvent (NULL, false, false, NULL);
|
2012-12-08 01:23:22 +08:00
|
|
|
if (wait_for_lock)
|
|
|
|
unlock ();
|
2012-12-05 04:26:18 +08:00
|
|
|
}
|
|
|
|
return signal_arrived;
|
2012-08-16 02:50:44 +08:00
|
|
|
}
|
2015-11-27 21:39:11 +08:00
|
|
|
void wait_signal_arrived (bool setit, HANDLE& h)
|
2012-07-22 06:58:20 +08:00
|
|
|
{
|
|
|
|
if (!setit)
|
2012-12-05 04:26:18 +08:00
|
|
|
will_wait_for_signal = false;
|
2012-07-22 06:58:20 +08:00
|
|
|
else
|
|
|
|
{
|
2012-12-05 04:26:18 +08:00
|
|
|
h = get_signal_arrived ();
|
|
|
|
will_wait_for_signal = true;
|
2012-07-22 06:58:20 +08:00
|
|
|
}
|
|
|
|
}
|
2015-11-27 21:39:11 +08:00
|
|
|
void set_signal_arrived ()
|
|
|
|
{
|
|
|
|
SetEvent (get_signal_arrived (false));
|
|
|
|
}
|
2013-04-09 09:01:19 +08:00
|
|
|
void reset_signal_arrived ()
|
|
|
|
{
|
|
|
|
if (signal_arrived)
|
|
|
|
ResetEvent (signal_arrived);
|
2015-11-27 21:39:11 +08:00
|
|
|
}
|
|
|
|
void unwait_signal_arrived ()
|
|
|
|
{
|
2013-04-09 09:01:19 +08:00
|
|
|
will_wait_for_signal = false;
|
|
|
|
}
|
|
|
|
void handle_SIGCONT ();
|
2022-02-22 18:18:38 +08:00
|
|
|
static void cleanup_early(struct _reent *);
|
2010-02-28 23:54:25 +08:00
|
|
|
private:
|
2022-05-24 03:52:52 +08:00
|
|
|
void call2 (DWORD (*) (void *, void *), void *, void *);
|
2015-10-23 20:30:40 +08:00
|
|
|
void remove_pending_sigs ();
|
2003-11-29 04:55:59 +08:00
|
|
|
};
|
|
|
|
#pragma pack(pop)
|
|
|
|
|
2013-04-23 17:44:36 +08:00
|
|
|
#include "cygerrno.h"
|
|
|
|
#include "ntdll.h"
|
|
|
|
|
2022-01-27 19:39:57 +08:00
|
|
|
#define _my_tls (*((_cygtls *) ((PBYTE) NtCurrentTeb()->Tib.StackBase \
|
|
|
|
- __CYGTLS_PADSIZE__)))
|
2004-02-12 11:01:58 +08:00
|
|
|
extern _cygtls *_main_tls;
|
2005-09-14 22:00:07 +08:00
|
|
|
extern _cygtls *_sig_tls;
|
2003-11-29 04:55:59 +08:00
|
|
|
|
2014-08-25 22:53:49 +08:00
|
|
|
class san
|
|
|
|
{
|
2015-07-08 02:45:06 +08:00
|
|
|
san *_clemente;
|
2014-08-26 03:47:44 +08:00
|
|
|
uint64_t _cnt;
|
2014-08-25 22:53:49 +08:00
|
|
|
public:
|
2015-07-08 02:45:06 +08:00
|
|
|
DWORD64 ret;
|
|
|
|
DWORD64 frame;
|
|
|
|
|
|
|
|
san (PVOID _ret) __attribute__ ((always_inline))
|
2014-08-25 22:53:49 +08:00
|
|
|
{
|
2015-07-08 02:45:06 +08:00
|
|
|
_clemente = _my_tls.andreas;
|
|
|
|
_my_tls.andreas = this;
|
2014-08-26 03:47:44 +08:00
|
|
|
_cnt = _my_tls.locals.pathbufs._counters;
|
2015-07-08 02:45:06 +08:00
|
|
|
/* myfault_altstack_handler needs the current stack pointer and the
|
|
|
|
address of the _except block to restore the context correctly.
|
|
|
|
See comment preceeding myfault_altstack_handler in exception.cc. */
|
|
|
|
ret = (DWORD64) _ret;
|
|
|
|
__asm__ volatile ("movq %%rsp,%0": "=o" (frame));
|
|
|
|
}
|
|
|
|
~san () __attribute__ ((always_inline))
|
|
|
|
{
|
|
|
|
_my_tls.andreas = _clemente;
|
2014-08-25 22:53:49 +08:00
|
|
|
}
|
2014-08-26 03:47:44 +08:00
|
|
|
/* This is the first thing called in the __except handler. The attribute
|
|
|
|
"returns_twice" makes sure that GCC disregards any register value set
|
|
|
|
earlier in the function, so this call serves as a register barrier. */
|
|
|
|
void leave () __attribute__ ((returns_twice));
|
2014-08-25 22:53:49 +08:00
|
|
|
};
|
2010-02-27 05:36:31 +08:00
|
|
|
|
2022-05-17 20:12:32 +08:00
|
|
|
/* Exception handling macros. This is a handmade SEH try/except. */
|
2014-08-22 17:21:33 +08:00
|
|
|
#define __mem_barrier __asm__ __volatile__ ("" ::: "memory")
|
|
|
|
#define __try \
|
|
|
|
{ \
|
|
|
|
__label__ __l_try, __l_except, __l_endtry; \
|
|
|
|
__mem_barrier; \
|
2015-07-08 02:45:06 +08:00
|
|
|
san __sebastian (&&__l_except); \
|
2014-08-22 17:21:33 +08:00
|
|
|
__asm__ goto ("\n" \
|
|
|
|
" .seh_handler _ZN9exception7myfaultEP17_EXCEPTION_RECORDPvP8_CONTEXTP19_DISPATCHER_CONTEXT, @except \n" \
|
|
|
|
" .seh_handlerdata \n" \
|
|
|
|
" .long 1 \n" \
|
|
|
|
" .rva %l[__l_try],%l[__l_endtry],%l[__l_except],%l[__l_except] \n" \
|
|
|
|
" .seh_code \n" \
|
|
|
|
: : : : __l_try, __l_endtry, __l_except); \
|
|
|
|
{ \
|
|
|
|
__l_try: \
|
|
|
|
__mem_barrier;
|
|
|
|
|
|
|
|
#define __leave \
|
|
|
|
goto __l_endtry
|
|
|
|
|
|
|
|
#define __except(__errno) \
|
|
|
|
goto __l_endtry; \
|
|
|
|
} \
|
|
|
|
{ \
|
|
|
|
__l_except: \
|
|
|
|
__mem_barrier; \
|
2014-08-25 22:53:49 +08:00
|
|
|
__sebastian.leave (); \
|
2014-08-22 17:21:33 +08:00
|
|
|
if (__errno) \
|
|
|
|
set_errno (__errno);
|
|
|
|
|
|
|
|
#define __endtry \
|
|
|
|
} \
|
|
|
|
__l_endtry: \
|
|
|
|
__mem_barrier; \
|
2010-02-27 05:36:31 +08:00
|
|
|
}
|
2014-08-22 17:21:33 +08:00
|
|
|
|
2015-11-27 21:39:11 +08:00
|
|
|
class wait_signal_arrived
|
2012-07-22 06:58:20 +08:00
|
|
|
{
|
|
|
|
public:
|
2015-11-27 21:39:11 +08:00
|
|
|
wait_signal_arrived (bool setit, HANDLE& h) { _my_tls.wait_signal_arrived (setit, h); }
|
|
|
|
wait_signal_arrived (HANDLE& h) { _my_tls.wait_signal_arrived (true, h); }
|
2012-07-22 06:58:20 +08:00
|
|
|
|
2012-12-05 04:26:18 +08:00
|
|
|
operator int () const {return _my_tls.will_wait_for_signal;}
|
2015-11-27 21:39:11 +08:00
|
|
|
/* Do not reset the signal_arrived event just because we leave the scope of
|
|
|
|
this wait_signal_arrived object. This may lead to all sorts of races.
|
|
|
|
The only method actually resetting the signal_arrived event is
|
|
|
|
_cygtls::call_signal_handler. */
|
|
|
|
~wait_signal_arrived () { _my_tls.unwait_signal_arrived (); }
|
2012-07-22 06:58:20 +08:00
|
|
|
};
|
|
|
|
/*gentls_offsets*/
|