1 static char rcsid[] = "$Id: except.c 47650 2011-09-17 04:45:25Z twu $";
2 #ifdef HAVE_CONFIG_H
3 #include <config.h>
4 #endif
5 
6 #include "except.h"
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>		/* For strcat */
10 #include "assert.h"
11 #include "bool.h"
12 
13 #ifdef HAVE_PTHREAD
14 #include <pthread.h>
15 #endif
16 
17 static bool raisep = true;
18 static bool threadedp = false;
19 
20 void
Except_inactivate()21 Except_inactivate () {
22   raisep = false;
23 }
24 
25 /* Used only for non-threaded runs */
26 Except_Frame_T global_except_stack = NULL;
27 
28 #ifdef HAVE_PTHREAD
29 static pthread_key_t global_except_key;
30 
31 void
Except_init_pthread()32 Except_init_pthread () {
33   threadedp = true;
34   pthread_key_create(&global_except_key,NULL);
35   return;
36 }
37 
38 void
Except_term_pthread()39 Except_term_pthread () {
40   /* Do not delete global_except_key, because worker threads might still need it */
41   /* pthread_key_delete(global_except_key); */
42   return;
43 }
44 
45 void
Except_stack_create()46 Except_stack_create () {
47   Except_Frame_T stackptr;
48 
49   stackptr = (Except_Frame_T) malloc(sizeof(*stackptr));
50   pthread_setspecific(global_except_key,stackptr);
51   return;
52 }
53 
54 void
Except_stack_destroy()55 Except_stack_destroy () {
56   Except_Frame_T stackptr;
57 
58   stackptr = (Except_Frame_T) pthread_getspecific(global_except_key);
59   free(stackptr);
60   return;
61 }
62 #endif
63 
64 void
Except_link_stack(Except_Frame_T frameptr)65 Except_link_stack (Except_Frame_T frameptr) {
66 #ifdef HAVE_PTHREAD
67   Except_Frame_T stackptr;
68 #endif
69 
70   if (threadedp == false) {
71     frameptr->prev = global_except_stack;
72     global_except_stack = frameptr;
73   } else {
74 #ifdef HAVE_PTHREAD
75     stackptr = (Except_Frame_T) pthread_getspecific(global_except_key);
76     frameptr->prev = stackptr;
77     stackptr = frameptr;
78 #endif
79   }
80 
81   return;
82 }
83 
84 Except_Frame_T
Except_advance_stack()85 Except_advance_stack () {
86 #ifdef HAVE_PTHREAD
87   Except_Frame_T stackptr;
88 
89   if (threadedp == false) {
90     global_except_stack = global_except_stack->prev;
91     return global_except_stack;
92   } else {
93     stackptr = (Except_Frame_T) pthread_getspecific(global_except_key);
94     stackptr = (stackptr)->prev;
95     return stackptr;
96   }
97 
98 #else
99   global_except_stack = global_except_stack->prev;
100   return global_except_stack;
101 #endif
102 }
103 
104 void
Except_raise(const Except_T * e,const char * file,int line)105 Except_raise (const Except_T *e, const char *file, int line) {
106   Except_Frame_T frameptr;
107   char message[512], piece[128];
108 #ifdef HAVE_PTHREAD
109   Except_Frame_T stackptr;
110 #endif
111 
112   assert(e);
113   message[0] = '\0';
114   if (e->reason) {
115     sprintf(piece," %s ", e->reason);
116     strcat(message,piece);
117   } else {
118     sprintf(piece," at 0x%p",(void *) e);
119     strcat(message,piece);
120   }
121   if (file && line > 0) {
122     sprintf(piece," raised at %s:%d",file,line);
123     strcat(message,piece);
124   }
125   fprintf(stderr,"Exception: %s\n",message);
126   fflush(stderr);
127 
128   if (threadedp == false) {
129     frameptr = global_except_stack;
130   } else {
131 #ifdef HAVE_PTHREAD
132     stackptr = (Except_Frame_T) pthread_getspecific(global_except_key);
133     frameptr = stackptr;
134 #endif
135   }
136 
137   if (frameptr == NULL) {
138     fprintf(stderr,"Uncaught exception: %s\n",message);
139     fflush(stderr);
140     abort();
141   } else {
142     frameptr->exception = e;
143     frameptr->file = file;
144     frameptr->line = line;
145     if (raisep == true) {
146       longjmp(frameptr->env,EXCEPT_RAISED);
147     } else {
148       fprintf(stderr,"Aborting...\n");
149       abort();
150     }
151   }
152   return;
153 }
154 
155 
156