Mercurial > octave-nkf
comparison libcruft/misc/cquit.c @ 5451:ed08548b9054
[project @ 2005-09-15 19:52:50 by jwe]
author | jwe |
---|---|
date | Thu, 15 Sep 2005 19:52:50 +0000 |
parents | 4c8a2e4e0717 |
children | ace8d8d26933 |
comparison
equal
deleted
inserted
replaced
5450:6b42c78c77d3 | 5451:ed08548b9054 |
---|---|
41 void | 41 void |
42 octave_restore_current_context (void *save_buf) | 42 octave_restore_current_context (void *save_buf) |
43 { | 43 { |
44 memcpy (current_context, save_buf, sizeof (octave_jmp_buf)); | 44 memcpy (current_context, save_buf, sizeof (octave_jmp_buf)); |
45 } | 45 } |
46 | |
47 #if defined (__WIN32__) && ! defined (_POSIX_VERSION) | |
48 | |
49 /* XXX FIXME XXX -- eventually remove the debugging */ | |
50 #if defined (DEBUG) | |
51 | |
52 #define PRINT_CURRENT_THREAD() printf ("%lx: ", GetCurrentThreadId ()) | |
53 | |
54 #define DEBUGs(s) \ | |
55 do \ | |
56 { \ | |
57 PRINT_CURRENT_THREAD (); \ | |
58 printf (s "\n"); \ | |
59 fflush (stdout); \ | |
60 } \ | |
61 while (0) | |
62 | |
63 #define DEBUGd(s, d) \ | |
64 do \ | |
65 { \ | |
66 PRINT_CURRENT_THREAD (); \ | |
67 printf (s "\n", d); \ | |
68 fflush (stdout); \ | |
69 } \ | |
70 while (0) | |
71 | |
72 #else | |
73 #define DEBUGs(s) | |
74 #define DEBUGd(s, d) | |
75 #endif | |
76 | |
77 CRITICAL_SECTION w32_thread_setjmp_mutex; | |
78 static CONTEXT w32_signal_context; | |
79 static int w32_signal_to_raise = 0; | |
80 static DWORD w32_main_thread_id; | |
81 static HANDLE w32_main_thread; | |
82 static HANDLE w32_restore_thread = NULL; | |
83 | |
84 int | |
85 w32_in_main_thread(void) | |
86 { | |
87 return (GetCurrentThreadId () == w32_main_thread_id); | |
88 } | |
89 | |
90 static DWORD WINAPI | |
91 w32_reset_context (LPVOID v) | |
92 { | |
93 PCONTEXT context = (PCONTEXT)v; | |
94 int ret; | |
95 | |
96 /* Mutex the setjmp/longjmp */ | |
97 EnterCriticalSection (&w32_thread_setjmp_mutex); | |
98 | |
99 DEBUGs ("enter w32_set_context"); | |
100 SuspendThread (w32_main_thread); | |
101 DEBUGs ("main suspended"); | |
102 if (! SetThreadContext (w32_main_thread, context)) | |
103 { | |
104 fprintf (stderr, "%lx: context failed: ctrl-c won't work\n", | |
105 GetCurrentThreadId ()); | |
106 fflush (stderr); | |
107 } | |
108 DEBUGs ("context captured (or not)"); | |
109 ret = ResumeThread (w32_main_thread); | |
110 DEBUGd ("main resumed with %d", ret); | |
111 | |
112 LeaveCriticalSection (&w32_thread_setjmp_mutex); | |
113 return 0; | |
114 } | |
115 | |
116 static void | |
117 w32_raise_in_main (void) | |
118 { | |
119 DWORD threadid; | |
120 | |
121 DEBUGd ("w32_raise_in_main with signal %d", w32_signal_to_raise); | |
122 raise (w32_signal_to_raise); | |
123 DEBUGd ("w32_raise_in_main signal %d returned a value", | |
124 w32_signal_to_raise); | |
125 | |
126 DEBUGs ("attempting to restore main to pre-signal configuration"); | |
127 if (w32_restore_thread != NULL) /* Catch leaky threads */ | |
128 CloseHandle (w32_restore_thread); | |
129 w32_restore_thread = CreateThread (NULL, 10000, w32_reset_context, | |
130 &w32_signal_context, 0, &threadid); | |
131 if (w32_restore_thread == NULL) | |
132 { | |
133 fprintf (stderr, "w32_raise_in_main couldn't create thread\n"); | |
134 fflush (stderr); | |
135 } | |
136 else | |
137 { | |
138 DEBUGs ("waiting to restore raise context"); | |
139 WaitForSingleObject (w32_restore_thread, INFINITE); | |
140 fprintf (stderr, "w32_raise_in_main couldn't restore context\n"); | |
141 fflush (stderr); | |
142 } | |
143 } | |
144 | |
145 void | |
146 w32_raise_final (void) | |
147 { | |
148 CloseHandle (w32_main_thread); | |
149 if (w32_restore_thread != NULL) /* Catch leaky threads */ | |
150 CloseHandle (w32_restore_thread); | |
151 w32_main_thread = w32_restore_thread = NULL; | |
152 } | |
153 | |
154 /* Raise the given signal in the main thread. w32_raise_init () | |
155 must have been called from the main thread already. */ | |
156 void | |
157 w32_raise (int sig) | |
158 { | |
159 int ret; | |
160 | |
161 if (w32_in_main_thread ()) | |
162 { | |
163 /* Called from main thread -- a simple raise () should work. */ | |
164 DEBUGd ("raising signal %d within main", signal); | |
165 raise (sig); | |
166 DEBUGd ("returning from signal %d within main", signal); | |
167 } | |
168 else | |
169 { | |
170 /* Called from alternate thread -- call w32_raise_in_main in the | |
171 main thread with w32_signal_to_raise set to the signal */ | |
172 CONTEXT raise_context; | |
173 DEBUGd ("raising signal %d from separate thread", signal); | |
174 | |
175 /* Suspend main and remember the context. */ | |
176 SuspendThread (w32_main_thread); | |
177 /* X86 code */ | |
178 w32_signal_context.ContextFlags | |
179 = CONTEXT_FULL|CONTEXT_FLOATING_POINT|CONTEXT_DEBUG_REGISTERS; | |
180 GetThreadContext (w32_main_thread, &w32_signal_context); | |
181 | |
182 /* Change the context to w32_raise_in_main. The | |
183 context.Eip=&fn trick for setting the program counter is | |
184 courtesy of | |
185 | |
186 http://fit.c2.com/files/LispPlatform/lisp/clisp-2.28/src/win32aux.d | |
187 | |
188 Auxiliary functions for CLISP on Win32, Bruno Haible | |
189 1997-1999. */ | |
190 | |
191 memcpy (&raise_context, &w32_signal_context, sizeof (CONTEXT)); | |
192 raise_context.Eip = (DWORD)&w32_raise_in_main; /* X86 code */ | |
193 w32_signal_to_raise = sig; | |
194 SetThreadContext (w32_main_thread, &raise_context); | |
195 | |
196 /* Resume main at w32_raise_in_main */ | |
197 ret = ResumeThread (w32_main_thread); | |
198 DEBUGd ("main resumed at w32_raise_in_main with suspend count %d", | |
199 ret); | |
200 } | |
201 } | |
202 | |
203 void | |
204 w32_sigint_init (void) | |
205 { | |
206 /* Capture main context */ | |
207 w32_main_thread_id = GetCurrentThreadId (); | |
208 DuplicateHandle (GetCurrentProcess (), GetCurrentThread (), | |
209 GetCurrentProcess (), &w32_main_thread, | |
210 0, FALSE, DUPLICATE_SAME_ACCESS); | |
211 | |
212 InitializeCriticalSectionAndSpinCount (&w32_thread_setjmp_mutex, 0); | |
213 } | |
214 | |
215 #endif /* #if defined (__WIN32__) && ! defined (_POSIX_VERSION) */ | |
46 | 216 |
47 void | 217 void |
48 octave_jump_to_enclosing_context (void) | 218 octave_jump_to_enclosing_context (void) |
49 { | 219 { |
50 #if defined (OCTAVE_HAVE_SIG_JUMP) | 220 #if defined (OCTAVE_HAVE_SIG_JUMP) |