27 |
#include <stdlib.h> |
#include <stdlib.h> |
28 |
#include "include.h" |
#include "include.h" |
29 |
|
|
30 |
|
static void |
31 |
|
invoke_handler(int,int); |
32 |
|
|
33 |
|
|
34 |
#ifndef USIG2 |
#ifndef USIG2 |
35 |
#include <signal.h> |
#include <signal.h> |
36 |
#include "usig.h" |
#include "usig.h" |
151 |
} |
} |
152 |
|
|
153 |
DO_INIT(init_safety();) |
DO_INIT(init_safety();) |
154 |
DEFUN("SIGNAL-SAFETY-REQUIRED",object,sSsignal_safety_required,SI,2,2, |
DEFUN_NEW("SIGNAL-SAFETY-REQUIRED",object,sSsignal_safety_required,SI,2,2, |
155 |
NONE,OI,IO,OO,OO, |
NONE,OI,IO,OO,OO,(int signo,int safety), |
156 |
"Set the safety level required for handling SIGNO to SAFETY, or if \ |
"Set the safety level required for handling SIGNO to SAFETY, or if \ |
157 |
SAFETY is negative just return the current safety level for that \ |
SAFETY is negative just return the current safety level for that \ |
158 |
signal number. Value of 1 means allow interrupt at any place not \ |
signal number. Value of 1 means allow interrupt at any place not \ |
159 |
specifically marked in the code as bad, and value of 2 means allow it \ |
specifically marked in the code as bad, and value of 2 means allow it \ |
160 |
only in very SAFE places.") |
only in very SAFE places.") |
161 |
|
|
|
|
|
|
|
|
|
(signo,safety) |
|
162 |
{ if (signo > sizeof(safety_required)) |
{ if (signo > sizeof(safety_required)) |
163 |
{FEerror("Illegal signo:~a.",1,make_fixnum(signo));} |
{FEerror("Illegal signo:~a.",1,make_fixnum(signo));} |
164 |
if (safety >=0) safety_required[signo] = safety; |
if (safety >=0) safety_required[signo] = safety; |
197 |
static void after_interrupt(struct save_for_interrupt *p, int allowed); |
static void after_interrupt(struct save_for_interrupt *p, int allowed); |
198 |
|
|
199 |
/* caller saves and restores the global signals_allowed; */ |
/* caller saves and restores the global signals_allowed; */ |
200 |
void |
static void |
201 |
invoke_handler(int signo, int allowed) |
invoke_handler(int signo, int allowed) |
202 |
{struct save_for_interrupt buf; |
{struct save_for_interrupt buf; |
203 |
before_interrupt(&buf,allowed); |
before_interrupt(&buf,allowed); |
326 |
and is suitable for inlining. |
and is suitable for inlining. |
327 |
*/ |
*/ |
328 |
|
|
329 |
object |
/* static object */ |
330 |
MakeCons(object a, object b) |
/* MakeCons(object a, object b) */ |
331 |
{ struct typemanager*ad = &tm_table[t_cons]; |
/* { struct typemanager*ad = &tm_table[t_cons]; */ |
332 |
object new = (object) ad->tm_free; |
/* object new = (object) ad->tm_free; */ |
333 |
if (new == 0) |
/* if (new == 0) */ |
334 |
{ new = alloc_object(t_cons); |
/* { new = alloc_object(t_cons); */ |
335 |
new->c.c_car = a; |
/* new->c.c_car = a; */ |
336 |
goto END; |
/* goto END; */ |
337 |
} |
/* } */ |
338 |
|
|
339 |
new->c.c_car=a; |
/* new->c.c_car=a; */ |
340 |
/* interrupt here and before_interrupt will copy new->c into the |
/* interrupt here and before_interrupt will copy new->c into the |
341 |
C stack, so that a will be protected */ |
C stack, so that a will be protected */ |
342 |
new->c.t=t_cons; |
/* new->c.t=t_cons; */ |
343 |
new->c.m= 0; |
/* new->c.m= 0; */ |
344 |
/* Make interrupt copy new out to the stack and then zero new. |
/* Make interrupt copy new out to the stack and then zero new. |
345 |
That way new is certainly gc valid, and its contents are protected. |
That way new is certainly gc valid, and its contents are protected. |
346 |
So the above three operations can occur in any order. |
So the above three operations can occur in any order. |
347 |
*/ |
*/ |
348 |
|
|
349 |
{ object tem = OBJ_LINK(new); |
/* { object tem = OBJ_LINK(new); */ |
350 |
/* |
/* |
351 |
interrupt here and we see that before_interrupt must save the top of the |
interrupt here and we see that before_interrupt must save the top of the |
352 |
free list AND the second thing on the Free list. That way we will be ok |
free list AND the second thing on the Free list. That way we will be ok |
354 |
== 0, yet a gc happened in between. An interrupt here when tem = 0 would |
== 0, yet a gc happened in between. An interrupt here when tem = 0 would |
355 |
mean the free list needs to be collected again by second gc. |
mean the free list needs to be collected again by second gc. |
356 |
*/ |
*/ |
357 |
ad->tm_free = tem; |
/* ad->tm_free = tem; */ |
358 |
} |
/* } */ |
359 |
/* Whew: we got it safely off so interrupts can't hurt us now. */ |
/* Whew: we got it safely off so interrupts can't hurt us now. */ |
360 |
ad->tm_nfree --; |
/* ad->tm_nfree --; */ |
361 |
/* interrupt here and the cdr field will point to a f_link which is |
/* interrupt here and the cdr field will point to a f_link which is |
362 |
a 'free' and so gc valid. b is still protected since |
a 'free' and so gc valid. b is still protected since |
363 |
it is in the stack or a regiseter, and a is protected since it is |
it is in the stack or a regiseter, and a is protected since it is |
364 |
in new, and new is not free |
in new, and new is not free |
365 |
*/ |
*/ |
366 |
END: |
/* END: */ |
367 |
new->c.c_cdr=b; |
/* new->c.c_cdr=b; */ |
368 |
return new; |
/* return new; */ |
369 |
} |
/* } */ |
370 |
|
|
371 |
|
|
372 |
/* COND is the condition where this is raised. |
/* COND is the condition where this is raised. |
401 |
}} |
}} |
402 |
|
|
403 |
|
|
404 |
DEFUN("ALLOW-SIGNAL",object,fSallow_signal,SI,1,1,NONE,OI,OO,OO,OO, |
DEFUN_NEW("ALLOW-SIGNAL",object,fSallow_signal,SI,1,1,NONE,OI,OO,OO,OO,(int n), |
405 |
"Install the default signal handler on signal N") |
"Install the default signal handler on signal N") |
406 |
(n) |
|
|
int n; |
|
407 |
{ |
{ |
408 |
|
|
409 |
signals_allowed |= signal_mask(n); |
signals_allowed |= signal_mask(n); |