- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/coroutine.cfa
r58b6d1b r76e069f 22 22 #include <string.h> 23 23 #include <unistd.h> 24 // use this define to make unwind.h play nice, definetely a hack 25 #define HIDE_EXPORTS 26 #include <unwind.h> 27 #undef HIDE_EXPORTS 24 28 #include <sys/mman.h> 25 29 } … … 29 33 #define __CFA_INVOKE_PRIVATE__ 30 34 #include "invoke.h" 35 36 extern "C" { 37 void _CtxCoroutine_Unwind(struct _Unwind_Exception * storage) __attribute__ ((__noreturn__)); 38 static void _CtxCoroutine_UnwindCleanup(_Unwind_Reason_Code, struct _Unwind_Exception *) __attribute__ ((__noreturn__)); 39 static void _CtxCoroutine_UnwindCleanup(_Unwind_Reason_Code, struct _Unwind_Exception *) { 40 abort(); 41 } 42 } 31 43 32 44 //----------------------------------------------------------------------------- … … 67 79 starter = NULL; 68 80 last = NULL; 69 } 70 71 void ^?{}(coroutine_desc& this) {} 81 cancellation = NULL; 82 } 83 84 void ^?{}(coroutine_desc& this) { 85 if(this.state != Halted) { 86 coroutine_desc * src = TL_GET( this_coroutine ); 87 coroutine_desc * dst = &this; 88 89 struct _Unwind_Exception storage; 90 storage.exception_class = -1; 91 storage.exception_cleanup = _CtxCoroutine_UnwindCleanup; 92 this.cancellation = &storage; 93 this.last = src; 94 95 // not resuming self ? 96 if ( src == dst ) { 97 abort( "Attempt by coroutine %.256s (%p) to terminate itself.\n", src->name, src ); 98 } 99 100 CoroutineCtxSwitch( src, dst ); 101 } 102 } 72 103 73 104 // Part of the Public API … … 105 136 // Safety note : This could cause some false positives due to preemption 106 137 verify( TL_GET( preemption_state.enabled ) || TL_GET( this_processor )->do_terminate ); 138 139 if( unlikely(src->cancellation != NULL) ) { 140 _CtxCoroutine_Unwind(src->cancellation); 141 } 107 142 } //ctxSwitchDirect 108 143 … … 162 197 } 163 198 164 void __leave_coroutine( void) {199 void __leave_coroutine() { 165 200 coroutine_desc * src = TL_GET( this_coroutine ); // optimization 166 167 assertf( src->starter != 0, 201 coroutine_desc * starter = src->cancellation != 0 ? src->last : src->starter; 202 203 src->state = Halted; 204 205 assertf( starter != 0, 168 206 "Attempt to suspend/leave coroutine \"%.256s\" (%p) that has never been resumed.\n" 169 207 "Possible cause is a suspend executed in a member called by a coroutine user rather than by the coroutine main.", 170 208 src->name, src ); 171 assertf( s rc->starter->state != Halted,209 assertf( starter->state != Halted, 172 210 "Attempt by coroutine \"%.256s\" (%p) to suspend/leave back to terminated coroutine \"%.256s\" (%p).\n" 173 211 "Possible cause is terminated coroutine's main routine has already returned.", 174 src->name, src, s rc->starter->name, src->starter );175 176 CoroutineCtxSwitch( src, s rc->starter );212 src->name, src, starter->name, starter ); 213 214 CoroutineCtxSwitch( src, starter ); 177 215 } 178 216 }
Note: See TracChangeset
for help on using the changeset viewer.