static struct replay_thread * thread_get(int fd, void *(*thread_main)(void *)) { assert(fd != 0); if (fd >= nthreads) { struct replay_thread **newthreads = threads; size_t newnthreads = nthreads; while (fd >= newnthreads) newnthreads += newnthreads + 1; newthreads = realloc(newthreads, newnthreads * sizeof *newthreads); XXXAN(newthreads != NULL); memset(newthreads + nthreads, 0, (newnthreads - nthreads) * sizeof *newthreads); threads = newthreads; nthreads = newnthreads; } if (threads[fd] == NULL) { threads[fd] = malloc(sizeof *threads[fd]); assert(threads[fd] != NULL); threads[fd]->sock = -1; thread_clear(threads[fd]); mailbox_create(&threads[fd]->mbox); if (pthread_create(&threads[fd]->thread_id, &thread_attr, thread_main, threads[fd]) != 0) { thread_log(0, errno, "pthread_create()"); mailbox_destroy(&threads[fd]->mbox); freez(threads[fd]); threads[fd] = THREAD_FAIL; } else { threads[fd]->fd = fd; thread_log(0, 0, "thread %p:%d started", (void *)threads[fd]->thread_id, fd); } } if (threads[fd] == THREAD_FAIL) return (NULL); return (threads[fd]); }
static void thread_close(int fd) { if (fd == -1) { for (fd = 0; fd < nthreads; ++fd) thread_close(fd); return; } assert(fd < nthreads); if (threads[fd] == NULL) return; mailbox_close(&threads[fd]->mbox); pthread_join(threads[fd]->thread_id, NULL); thread_log(0, 0, "thread %p stopped", (void *)threads[fd]->thread_id); thread_clear(threads[fd]); mailbox_destroy(&threads[fd]->mbox); freez(threads[fd]); }
static int l_mailbox_ref_destroy(lua_State *L) { mailbox_ref_t *ref; ref = luaL_checkudata(L, 1, MAILBOX_REF_TYPE_NAME); mailbox_destroy(ref); return 0; }