int SLNPullStart(SLNPullRef const pull) { if(!pull) return 0; if(!pull->stop) return 0; assert(0 == pull->tasks); pull->stop = false; for(size_t i = 0; i < READER_COUNT; ++i) { pull->tasks++; async_spawn(STACK_DEFAULT, (void (*)())reader, pull); } pull->tasks++; async_spawn(STACK_DEFAULT, (void (*)())writer, pull); // TODO: It'd be even better to have one writer shared between all pulls... return 0; }
int EFSSyncCreate(EFSSessionRef const session, strarg_t const syncID, EFSSyncRef *const out) { assert(out); if(!syncID) return UV_EINVAL; EFSSyncRef sync = calloc(1, sizeof(struct EFSSync)); if(!sync) return UV_ENOMEM; sync->session = session; syncID = strdup(syncID); if(!syncID) { EFSSyncFree(&sync); return UV_ENOMEM; } async_mutex_init(sync->mutex, 0); async_cond_init(sync->cond, ASYNC_CANCELABLE); sync->cur = &sync->queues[0]; int rc = async_spawn(STACK_DEFAULT, db_thread, sync); if(rc < 0) { EFSSyncFree(&sync); return rc; } *out = sync; return 0; }
int main(int const argc, char const *const *const argv) { // Depending on how async_pool and async_fs are configured, we might be // using our own thread pool heavily or not. However, at the minimum, // uv_getaddrinfo uses the libuv thread pool, and it blocks on the // network, so don't set this number too low. if(!getenv("UV_THREADPOOL_SIZE")) putenv((char *)"UV_THREADPOOL_SIZE=4"); raiserlimit(); async_init(); int rc = tls_init(); if(rc < 0) { alogf("TLS initialization error: %s\n", strerror(errno)); return 1; } if(2 != argc || '-' == argv[1][0]) { alogf("Usage:\n\t" "%s repo\n", argv[0]); return 1; } path = argv[1]; // Even our init code wants to use async I/O. async_spawn(STACK_DEFAULT, init, NULL); uv_run(async_loop, UV_RUN_DEFAULT); async_spawn(STACK_DEFAULT, term, NULL); uv_run(async_loop, UV_RUN_DEFAULT); // cleanup is separate from term because connections might // still be active. async_spawn(STACK_DEFAULT, cleanup, NULL); uv_run(async_loop, UV_RUN_DEFAULT); async_destroy(); // TODO: Windows? if(sig) raise(sig); return 0; }
static void connection_cb(uv_stream_t *const socket, int const status) { async_spawn(STACK_DEFAULT, (void (*)())connection, socket); }