comparison src/unwind-prot.cc @ 2985:aa9d0c0e0458

[project @ 1997-05-16 06:54:18 by jwe]
author jwe
date Fri, 16 May 1997 06:55:52 +0000
parents 8b262e771614
children 5708b8bb4f06
comparison
equal deleted inserted replaced
2984:84c33881d0bc 2985:aa9d0c0e0458
38 38
39 #include "error.h" 39 #include "error.h"
40 #include "unwind-prot.h" 40 #include "unwind-prot.h"
41 #include "utils.h" 41 #include "utils.h"
42 42
43 // XXX FIXME XXX -- this should really be static, but that causes 43 SLStack<unwind_elem> unwind_protect::list;
44 // problems on some systems. 44
45 SLStack <unwind_elem> unwind_protect_list; 45 class
46 46 saved_variable
47 void 47 {
48 add_unwind_protect (cleanup_func fptr, void *ptr) 48 public:
49 { 49
50 unwind_elem el (fptr, ptr); 50 enum var_type
51 unwind_protect_list.push (el); 51 {
52 } 52 boolean,
53 53 integer,
54 void 54 string_type,
55 run_unwind_protect (void) 55 generic_ptr,
56 { 56 generic
57 unwind_elem el = unwind_protect_list.pop (); 57 };
58
59 cleanup_func f = el.fptr ();
60
61 if (f)
62 f (el.ptr ());
63 }
64
65 void
66 discard_unwind_protect (void)
67 {
68 unwind_protect_list.pop ();
69 }
70
71 void
72 begin_unwind_frame (const string& tag)
73 {
74 unwind_elem elem (tag);
75 unwind_protect_list.push (elem);
76 }
77
78 void
79 run_unwind_frame (const string& tag)
80 {
81 while (! unwind_protect_list.empty ())
82 {
83 unwind_elem el = unwind_protect_list.pop ();
84
85 cleanup_func f = el.fptr ();
86
87 if (f)
88 f (el.ptr ());
89
90 if (tag == el.tag ())
91 break;
92 }
93 }
94
95 void
96 discard_unwind_frame (const string& tag)
97 {
98 while (! unwind_protect_list.empty ())
99 {
100 unwind_elem el = unwind_protect_list.pop ();
101
102 if (tag == el.tag ())
103 break;
104 }
105 }
106
107 void
108 run_all_unwind_protects (void)
109 {
110 while (! unwind_protect_list.empty ())
111 {
112 unwind_elem el = unwind_protect_list.pop ();
113
114 cleanup_func f = el.fptr ();
115
116 if (f)
117 f (el.ptr ());
118 }
119 }
120
121 void
122 discard_all_unwind_protects (void)
123 {
124 unwind_protect_list.clear ();
125 }
126
127 class saved_variable
128 {
129 public:
130 enum var_type { integer, string_type, generic_ptr, generic };
131 58
132 saved_variable (void); 59 saved_variable (void);
60
61 saved_variable (bool *p, bool v);
62
133 saved_variable (int *p, int v); 63 saved_variable (int *p, int v);
64
134 saved_variable (string *p, const string& v); 65 saved_variable (string *p, const string& v);
66
135 saved_variable (void **p, void *v); 67 saved_variable (void **p, void *v);
68
136 ~saved_variable (void); 69 ~saved_variable (void);
137 70
138 void restore_value (void); 71 void restore_value (void);
139 72
140 private: 73 static void restore (void *s);
74
75 private:
76
141 union 77 union
142 { 78 {
79 bool *ptr_to_bool;
143 int *ptr_to_int; 80 int *ptr_to_int;
144 void *gen_ptr; 81 void *gen_ptr;
145 void **ptr_to_gen_ptr; 82 void **ptr_to_gen_ptr;
146 }; 83 };
147 84
148 union 85 union
149 { 86 {
87 bool bool_value;
150 int int_value; 88 int int_value;
151 const string *str_value; 89 const string *str_value;
152 void *gen_ptr_value; 90 void *gen_ptr_value;
153 }; 91 };
154 92
155 var_type type_tag; 93 var_type type_tag;
94
156 size_t size; 95 size_t size;
157 }; 96 };
158 97
159 saved_variable::saved_variable (void) 98 saved_variable::saved_variable (void)
160 { 99 {
162 gen_ptr_value = 0; 101 gen_ptr_value = 0;
163 type_tag = generic; 102 type_tag = generic;
164 size = 0; 103 size = 0;
165 } 104 }
166 105
106 saved_variable::saved_variable (bool *p, bool v)
107 {
108 type_tag = integer;
109 ptr_to_bool = p;
110 bool_value = v;
111 size = sizeof (bool); // Is this necessary?
112 }
113
167 saved_variable::saved_variable (int *p, int v) 114 saved_variable::saved_variable (int *p, int v)
168 { 115 {
169 type_tag = integer; 116 type_tag = integer;
170 ptr_to_int = p; 117 ptr_to_int = p;
171 int_value = v; 118 int_value = v;
208 void 155 void
209 saved_variable::restore_value (void) 156 saved_variable::restore_value (void)
210 { 157 {
211 switch (type_tag) 158 switch (type_tag)
212 { 159 {
160 case boolean:
161 *ptr_to_bool = bool_value;
162 break;
163
213 case integer: 164 case integer:
214 *ptr_to_int = int_value; 165 *ptr_to_int = int_value;
215 break; 166 break;
216 167
217 case string_type: 168 case string_type:
230 panic_impossible (); 181 panic_impossible ();
231 break; 182 break;
232 } 183 }
233 } 184 }
234 185
235 static void 186 void
236 restore_saved_variable (void *s) 187 saved_variable::restore (void *s)
237 { 188 {
238 saved_variable *sv = static_cast<saved_variable *> (s); 189 saved_variable *sv = static_cast<saved_variable *> (s);
239 sv->restore_value (); 190 sv->restore_value ();
240 delete sv; 191 delete sv;
241 } 192 }
242 193
243 void 194 void
244 unwind_protect_int_internal (int *ptr, int value) 195 unwind_protect::add (unwind_elem::cleanup_func fptr, void *ptr)
196 {
197 unwind_elem el (fptr, ptr);
198 list.push (el);
199 }
200
201 void
202 unwind_protect::run (void)
203 {
204 unwind_elem el = list.pop ();
205
206 unwind_elem::cleanup_func f = el.fptr ();
207
208 if (f)
209 f (el.ptr ());
210 }
211
212 void
213 unwind_protect::discard (void)
214 {
215 list.pop ();
216 }
217
218 void
219 unwind_protect::begin_frame (const string& tag)
220 {
221 unwind_elem elem (tag);
222 list.push (elem);
223 }
224
225 void
226 unwind_protect::run_frame (const string& tag)
227 {
228 while (! list.empty ())
229 {
230 unwind_elem el = list.pop ();
231
232 unwind_elem::cleanup_func f = el.fptr ();
233
234 if (f)
235 f (el.ptr ());
236
237 if (tag == el.tag ())
238 break;
239 }
240 }
241
242 void
243 unwind_protect::discard_frame (const string& tag)
244 {
245 while (! list.empty ())
246 {
247 unwind_elem el = list.pop ();
248
249 if (tag == el.tag ())
250 break;
251 }
252 }
253
254 void
255 unwind_protect::run_all (void)
256 {
257 while (! list.empty ())
258 {
259 unwind_elem el = list.pop ();
260
261 unwind_elem::cleanup_func f = el.fptr ();
262
263 if (f)
264 f (el.ptr ());
265 }
266 }
267
268 void
269 unwind_protect::discard_all (void)
270 {
271 list.clear ();
272 }
273
274 void
275 unwind_protect::save_bool (bool *ptr, bool value)
245 { 276 {
246 saved_variable *s = new saved_variable (ptr, value); 277 saved_variable *s = new saved_variable (ptr, value);
247 add_unwind_protect (restore_saved_variable, s); 278 add (saved_variable::restore, s);
248 } 279 }
249 280
250 void 281 void
251 unwind_protect_str_internal (string *ptr, const string& value) 282 unwind_protect::save_int (int *ptr, int value)
252 { 283 {
253 saved_variable *s = new saved_variable (ptr, value); 284 saved_variable *s = new saved_variable (ptr, value);
254 add_unwind_protect (restore_saved_variable, s); 285 add (saved_variable::restore, s);
255 } 286 }
256 287
257 void 288 void
258 unwind_protect_ptr_internal (void **ptr, void *value) 289 unwind_protect::save_str (string *ptr, const string& value)
259 { 290 {
260 saved_variable *s = new saved_variable (ptr, value); 291 saved_variable *s = new saved_variable (ptr, value);
261 add_unwind_protect (restore_saved_variable, s); 292 add (saved_variable::restore, s);
293 }
294
295 void
296 unwind_protect::save_ptr (void **ptr, void *value)
297 {
298 saved_variable *s = new saved_variable (ptr, value);
299 add (saved_variable::restore, s);
262 } 300 }
263 301
264 /* 302 /*
265 ;;; Local Variables: *** 303 ;;; Local Variables: ***
266 ;;; mode: C++ *** 304 ;;; mode: C++ ***