Ignore:
Timestamp:
Oct 26, 2020, 12:17:28 PM (6 years ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum, stuck-waitfor-destruct
Children:
342be43
Parents:
912cc7d7
Message:

Thread Cancellation, a test for it and a required fix to Specialization.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/thread.cfa

    r912cc7d7 rab8c6a6  
    1919
    2020#include "kernel_private.hfa"
     21#include "exception.hfa"
    2122
    2223#define __CFA_INVOKE_PRIVATE__
     
    5859}
    5960
     61FORALL_DATA_INSTANCE(ThreadCancelled, (dtype thread_t), (thread_t))
     62
     63forall(dtype T)
     64void copy(ThreadCancelled(T) * dst, ThreadCancelled(T) * src) {
     65        dst->virtual_table = src->virtual_table;
     66        dst->the_thread = src->the_thread;
     67        dst->the_exception = src->the_exception;
     68}
     69
     70forall(dtype T)
     71const char * msg(ThreadCancelled(T) *) {
     72        return "ThreadCancelled";
     73}
     74
     75struct __cfaehm_node {
     76        struct _Unwind_Exception unwind_exception;
     77        struct __cfaehm_node * next;
     78        int handler_index;
     79};
     80
     81forall(dtype T)
     82static void default_thread_cancel_handler(ThreadCancelled(T) & ) {
     83        abort( "Unhandled thread cancellation.\n" );
     84}
     85
     86forall(dtype T | is_thread(T) | IS_EXCEPTION(ThreadCancelled, (T)))
     87void ?{}( thread_dtor_guard_t & this,
     88                T & thrd, void(*defaultResumptionHandler)(ThreadCancelled(T) &)) {
     89        $monitor * m = get_monitor(thrd);
     90        void (*dtor)(T& mutex this) = ^?{};
     91        bool join = defaultResumptionHandler != (void(*)(ThreadCancelled(T)&))0;
     92        (this.mg){&m, (void(*)())dtor, join};
     93        {
     94                $thread * desc = get_thread(thrd);
     95                struct _Unwind_Exception * cancellation = desc->self_cor.cancellation;
     96                if ( likely(0p == cancellation) ) {
     97                        return;
     98                } else if ( Cancelled == desc->state ) {
     99                        return;
     100                }
     101                desc->state = Cancelled;
     102                if (!join) {
     103                        defaultResumptionHandler = default_thread_cancel_handler;
     104                }
     105                ThreadCancelled(T) except;
     106                // TODO: Remove explitate vtable set once trac#186 is fixed.
     107                except.virtual_table = &get_exception_vtable(&except);
     108                except.the_thread = &thrd;
     109                except.the_exception = (exception_t *)(1 + (__cfaehm_node *)cancellation);
     110                throwResume except;
     111
     112                except.the_exception->virtual_table->free( except.the_exception );
     113                free( cancellation );
     114                desc->self_cor.cancellation = 0p;
     115        }
     116}
     117
     118void ^?{}( thread_dtor_guard_t & this ) {
     119        ^(this.mg){};
     120}
     121
    60122//-----------------------------------------------------------------------------
    61123// Starting and stopping threads
     
    93155}
    94156
     157//-----------------------------------------------------------------------------
     158forall(dtype T | is_thread(T) | IS_RESUMPTION_EXCEPTION(ThreadCancelled, (T)))
     159T & join( T & this ) {
     160        thread_dtor_guard_t guard = { this, defaultResumptionHandler };
     161        return this;
     162}
     163
    95164// Local Variables: //
    96165// mode: c //
Note: See TracChangeset for help on using the changeset viewer.