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