/* * Arguments: pipe_udata */ static int pipe_close (lua_State *L) { struct pipe_ref *pr = checkudata(L, 1, PIPE_TYPENAME); struct pipe *pp = pr->pipe; if (pp) { thread_critsect_t *csp = pipe_critsect_ptr(pp); int nref; thread_critsect_enter(csp); nref = pp->nref--; thread_critsect_leave(csp); if (!nref) { thread_critsect_del(&pp->cs); thread_cond_del(&pp->put_cond); thread_cond_del(&pp->get_cond); /* deallocate buffers */ if (pp->rbuf) { struct pipe_buf *rpb = pp->rbuf, *wpb = pp->wbuf; do { struct pipe_buf *pb = rpb->next_buf; free(rpb); rpb = pb; } while (rpb != wpb); } free(pp); } pr->pipe = NULL; } return 0; }
static int channel_done (lua_State *L) { struct channel *chan = checkudata(L, 1, CHANNEL_TYPENAME); thread_cond_del(&chan->put); thread_cond_del(&chan->get); thread_critsect_del(&chan->mutex); return 0; }
/* * Arguments: thread_udata */ static int thread_done (lua_State *L) { struct sys_thread *td = checkudata(L, 1, THREAD_TYPENAME); if (td->L) { if (thread_isvm(td)) { thread_critsect_leave(td->vmcsp); thread_critsect_del(td->vmcsp); } else { sys_vm2_leave(td); #ifndef _WIN32 { THREAD_FUNC_RES v; pthread_join(td->tid, &v); } #else WaitForSingleObject(td->tid, INFINITE); CloseHandle(td->tid); #endif sys_vm2_enter(td); } (void) thread_cond_del(&td->cond); lua_rawgetp(L, LUA_REGISTRYINDEX, THREAD_KEY_ADDRESS); lua_pushnil(L); lua_rawsetp(L, -2, td->L); /* coroutine */ lua_pop(L, 1); td->L = NULL; } return 0; }