/** thread_stack : 'thread -> array <doc> Get the thread current call stack. Might crash if the thread currently manipulate the stack, so mostly used to debug infinite loops. </doc> **/ static value thread_stack( value vt ) { vthread *t; val_check_kind(vt,k_thread); t = val_thread(vt); if( t->vm == NULL ) neko_error(); return neko_call_stack(t->vm); }
/** thread_send : 'thread -> msg:any -> void <doc>Send a message into the target thread message queue</doc> **/ static value thread_send( value vt, value msg ) { vthread *t; val_check_kind(vt,k_thread); t = val_thread(vt); _deque_add(&t->q,msg); return val_null; }
/** thread_read_message : block:bool -> any <doc> Reads a message from the message queue. If [block] is true, the function only returns when a message is available. If [block] is false and no message is available in the queue, the function will return immediatly [null]. </doc> **/ static value thread_read_message( value block ) { value v = thread_current(); vthread *t; if( v == NULL ) neko_error(); t = val_thread(v); val_check(block,bool); return _deque_pop( &t->q, val_bool(block) ); }
static value thread_equal(value t1, value t2) { vthread *thread1, *thread2; vkind k_thread = kind_import("thread"); value rv; val_check_kind(t1,k_thread); val_check_kind(t2,k_thread); thread1 = val_thread(t1); thread2 = val_thread(t2); rv = val_false; #ifdef NEKO_WINDOWS if(thread1->tid == thread2->tid) #else if(thread1->phandle == thread2->phandle) #endif rv = val_true; return rv; }
static void free_thread( value v ) { vthread *t = val_thread(v); _deque_destroy(&t->q); }