#if !defined __lanes_private_h__ #define __lanes_private_h__ 1 #include "uniquekey.h" #include "cancel.h" // NOTE: values to be changed by either thread, during execution, without // locking, are marked "volatile" // struct s_Lane { THREAD_T thread; // // M: sub-thread OS thread // S: not used char const* debug_name; lua_State* L; Universe* U; // // M: prepares the state, and reads results // S: while S is running, M must keep out of modifying the state volatile enum e_status status; // // M: sets to PENDING (before launching) // S: updates -> RUNNING/WAITING -> DONE/ERROR_ST/CANCELLED SIGNAL_T* volatile waiting_on; // // When status is WAITING, points on the linda's signal the thread waits on, else NULL volatile enum e_cancel_request cancel_request; // // M: sets to FALSE, flags TRUE for cancel request // S: reads to see if cancel is requested #if THREADWAIT_METHOD == THREADWAIT_CONDVAR SIGNAL_T done_signal; // // M: Waited upon at lane ending (if Posix with no PTHREAD_TIMEDJOIN) // S: sets the signal once cancellation is noticed (avoids a kill) MUTEX_T done_lock; // // Lock required by 'done_signal' condition variable, protecting // lane status changes to DONE/ERROR_ST/CANCELLED. #endif // THREADWAIT_METHOD == THREADWAIT_CONDVAR volatile enum { NORMAL, // normal master side state KILLED // issued an OS kill } mstatus; // // M: sets to NORMAL, if issued a kill changes to KILLED // S: not used struct s_Lane* volatile selfdestruct_next; // // M: sets to non-NULL if facing lane handle '__gc' cycle but the lane // is still running // S: cleans up after itself if non-NULL at lane exit #if HAVE_LANE_TRACKING struct s_Lane* volatile tracking_next; #endif // HAVE_LANE_TRACKING // // For tracking only }; typedef struct s_Lane Lane; // To allow free-running threads (longer lifespan than the handle's) // 'Lane' are malloc/free'd and the handle only carries a pointer. // This is not deep userdata since the handle's not portable among lanes. // #define lua_toLane( L, i) (*((Lane**) luaL_checkudata( L, i, "Lane"))) static inline Lane* get_lane_from_registry( lua_State* L) { Lane* s; STACK_GROW( L, 1); STACK_CHECK( L, 0); REGISTRY_GET( L, CANCEL_TEST_KEY); s = lua_touserdata( L, -1); // lightuserdata (true 's_lane' pointer) / nil lua_pop( L, 1); STACK_END( L, 0); return s; } int push_thread_status( lua_State* L, Lane* s); #endif // __lanes_private_h__