void MCFiberCall(MCFiberRef p_target, MCFiberCallback p_callback, void *p_context) { // If we are on the given fiber, call the callback directly. if (p_target == s_fiber_current) { p_callback(p_context); return; } // Otherwise, set the fields in the fiber's structure. p_target -> callback = p_callback; p_target -> context = p_context; p_target -> caller = s_fiber_current; // And switch to the fiber. MCFiberMakeCurrent(p_target); }
void MCFiberDestroy(MCFiberRef self) { // A fiber can only be destroyed at zero depth. MCAssert(self -> depth == 0); // If the thread is owned by the fiber then wait on it to finish. if (self -> owns_thread && self -> thread != nil) { // A fiber that owns its thread cannot destroy itself. MCAssert(self != s_fiber_current); // Loop until the thread is finished. while(!self -> finished) MCFiberMakeCurrent(self); // Join to the thread. pthread_join(self -> thread, nil); // The thread is now gone. self -> thread = nil; } // Remove the fiber record from the list. if (s_fibers != self) { MCFiber *t_previous; for(t_previous = s_fibers; t_previous -> next != self; t_previous = t_previous -> next) ; t_previous -> next = self -> next; } else s_fibers = self -> next; // Delete the record. MCMemoryDelete(self); // If there are now no fibers, finalize our state. if (s_fibers == nil) MCFiberFinalize(); }