static void *run_thread(void *start_arg) { assert(start_arg != NULL); struct start_arg *start = start_arg; thread_t *thread = start->thread; assert(thread != NULL); if (prctl(PR_SET_NAME, (unsigned long)thread->name) == -1) { ALOGE("%s unable to set thread name: %s", __func__, strerror(errno)); start->error = errno; semaphore_post(start->start_sem); return NULL; } thread->tid = gettid(); semaphore_post(start->start_sem); reactor_object_t work_queue_object; work_queue_object.context = thread->work_queue; work_queue_object.fd = fixed_queue_get_dequeue_fd(thread->work_queue); work_queue_object.interest = REACTOR_INTEREST_READ; work_queue_object.read_ready = work_queue_read_cb; reactor_register(thread->reactor, &work_queue_object); reactor_start(thread->reactor); // Make sure we dispatch all queued work items before exiting the thread. // This allows a caller to safely tear down by enqueuing a teardown // work item and then joining the thread. size_t count = 0; work_item_t *item = fixed_queue_try_dequeue(thread->work_queue); while (item && count <= WORK_QUEUE_CAPACITY) { item->func(item->context); free(item); item = fixed_queue_try_dequeue(thread->work_queue); ++count; } if (count > WORK_QUEUE_CAPACITY) ALOGD("%s growing event queue on shutdown.", __func__); return NULL; }
static void *run_thread(void *start_arg) { assert(start_arg != NULL); struct start_arg *start = start_arg; thread_t *thread = start->thread; assert(thread != NULL); if (prctl(PR_SET_NAME, (unsigned long)thread->name) == -1) { LOG_ERROR("%s unable to set thread name: %s", __func__, strerror(errno)); start->error = errno; semaphore_post(start->start_sem); return NULL; } thread->tid = gettid(); semaphore_post(start->start_sem); int fd = fixed_queue_get_dequeue_fd(thread->work_queue); void *context = thread->work_queue; reactor_object_t *work_queue_object = reactor_register(thread->reactor, fd, context, work_queue_read_cb, NULL); reactor_start(thread->reactor); reactor_unregister(work_queue_object); // Make sure we dispatch all queued work items before exiting the thread. // This allows a caller to safely tear down by enqueuing a teardown // work item and then joining the thread. size_t count = 0; work_item_t *item = fixed_queue_try_dequeue(thread->work_queue); while (item && count <= fixed_queue_capacity(thread->work_queue)) { item->func(item->context); osi_free(item); item = fixed_queue_try_dequeue(thread->work_queue); ++count; } if (count > fixed_queue_capacity(thread->work_queue)) LOG_DEBUG("%s growing event queue on shutdown.", __func__); return NULL; }