int iothread_perform_impl(void_function_t &&func, void_function_t &&completion) { ASSERT_IS_MAIN_THREAD(); ASSERT_IS_NOT_FORKED_CHILD(); iothread_init(); struct spawn_request_t req(std::move(func), std::move(completion)); int local_thread_count = -1; bool spawn_new_thread = false; { // Lock around a local region. auto &&locker = s_spawn_requests.acquire(); thread_data_t &td = locker.value; td.request_queue.push(std::move(req)); if (td.thread_count < IO_MAX_THREADS) { td.thread_count++; spawn_new_thread = true; } local_thread_count = td.thread_count; } // Kick off the thread if we decided to do so. if (spawn_new_thread) { iothread_spawn(); } return local_thread_count; }
int iothread_perform_base(int (*handler)(void *), void (*completionCallback)(void *, int), void *context) { ASSERT_IS_MAIN_THREAD(); ASSERT_IS_NOT_FORKED_CHILD(); iothread_init(); // Create and initialize a request. struct SpawnRequest_t *req = new SpawnRequest_t(); req->handler = handler; req->completionCallback = completionCallback; req->context = context; int local_thread_count = -1; bool spawn_new_thread = false; { // Lock around a local region. Note that we can only access s_active_thread_count under the // lock. scoped_lock lock(s_spawn_queue_lock); add_to_queue(req); if (s_active_thread_count < IO_MAX_THREADS) { s_active_thread_count++; spawn_new_thread = true; } local_thread_count = s_active_thread_count; } // Kick off the thread if we decided to do so. if (spawn_new_thread) { iothread_spawn(); } // We return the active thread count for informational purposes only. return local_thread_count; }
int iothread_port(void) { iothread_init(); return s_read_pipe; }