1c72fcc34Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 2c72fcc34Sopenharmony_ci// 3c72fcc34Sopenharmony_ci// waiter.c - I/O event waiter. 4c72fcc34Sopenharmony_ci// 5c72fcc34Sopenharmony_ci// Copyright (c) 2018 Takashi Sakamoto <o-takashi@sakamocchi.jp> 6c72fcc34Sopenharmony_ci// 7c72fcc34Sopenharmony_ci// Licensed under the terms of the GNU General Public License, version 2. 8c72fcc34Sopenharmony_ci 9c72fcc34Sopenharmony_ci#include "waiter.h" 10c72fcc34Sopenharmony_ci 11c72fcc34Sopenharmony_ci#include <stdlib.h> 12c72fcc34Sopenharmony_ci#include <string.h> 13c72fcc34Sopenharmony_ci#include <errno.h> 14c72fcc34Sopenharmony_ci 15c72fcc34Sopenharmony_ci#include "misc.h" 16c72fcc34Sopenharmony_ci 17c72fcc34Sopenharmony_cistatic const char *const waiter_type_labels[] = { 18c72fcc34Sopenharmony_ci [WAITER_TYPE_DEFAULT] = "default", 19c72fcc34Sopenharmony_ci [WAITER_TYPE_POLL] = "poll", 20c72fcc34Sopenharmony_ci [WAITER_TYPE_SELECT] = "select", 21c72fcc34Sopenharmony_ci [WAITER_TYPE_EPOLL] = "epoll", 22c72fcc34Sopenharmony_ci}; 23c72fcc34Sopenharmony_ci 24c72fcc34Sopenharmony_cienum waiter_type waiter_type_from_label(const char *label) 25c72fcc34Sopenharmony_ci{ 26c72fcc34Sopenharmony_ci int i; 27c72fcc34Sopenharmony_ci 28c72fcc34Sopenharmony_ci for (i = 0; i < (int)ARRAY_SIZE(waiter_type_labels); ++i) { 29c72fcc34Sopenharmony_ci if (!strcmp(waiter_type_labels[i], label)) 30c72fcc34Sopenharmony_ci return i; 31c72fcc34Sopenharmony_ci } 32c72fcc34Sopenharmony_ci 33c72fcc34Sopenharmony_ci return WAITER_TYPE_DEFAULT; 34c72fcc34Sopenharmony_ci} 35c72fcc34Sopenharmony_ci 36c72fcc34Sopenharmony_ciconst char *waiter_label_from_type(enum waiter_type type) 37c72fcc34Sopenharmony_ci{ 38c72fcc34Sopenharmony_ci return waiter_type_labels[type]; 39c72fcc34Sopenharmony_ci} 40c72fcc34Sopenharmony_ci 41c72fcc34Sopenharmony_ciint waiter_context_init(struct waiter_context *waiter, 42c72fcc34Sopenharmony_ci enum waiter_type type, unsigned int pfd_count) 43c72fcc34Sopenharmony_ci{ 44c72fcc34Sopenharmony_ci struct { 45c72fcc34Sopenharmony_ci enum waiter_type type; 46c72fcc34Sopenharmony_ci const struct waiter_data *waiter; 47c72fcc34Sopenharmony_ci } entries[] = { 48c72fcc34Sopenharmony_ci {WAITER_TYPE_POLL, &waiter_poll}, 49c72fcc34Sopenharmony_ci {WAITER_TYPE_SELECT, &waiter_select}, 50c72fcc34Sopenharmony_ci {WAITER_TYPE_EPOLL, &waiter_epoll}, 51c72fcc34Sopenharmony_ci }; 52c72fcc34Sopenharmony_ci int i; 53c72fcc34Sopenharmony_ci 54c72fcc34Sopenharmony_ci if (pfd_count == 0) 55c72fcc34Sopenharmony_ci return -EINVAL; 56c72fcc34Sopenharmony_ci 57c72fcc34Sopenharmony_ci for (i = 0; i < (int)ARRAY_SIZE(entries); ++i) { 58c72fcc34Sopenharmony_ci if (entries[i].type == type) 59c72fcc34Sopenharmony_ci break; 60c72fcc34Sopenharmony_ci } 61c72fcc34Sopenharmony_ci if (i == ARRAY_SIZE(entries)) 62c72fcc34Sopenharmony_ci return -EINVAL; 63c72fcc34Sopenharmony_ci 64c72fcc34Sopenharmony_ci waiter->private_data = malloc(entries[i].waiter->private_size); 65c72fcc34Sopenharmony_ci if (waiter->private_data == NULL) 66c72fcc34Sopenharmony_ci return -ENOMEM; 67c72fcc34Sopenharmony_ci memset(waiter->private_data, 0, entries[i].waiter->private_size); 68c72fcc34Sopenharmony_ci 69c72fcc34Sopenharmony_ci waiter->type = type; 70c72fcc34Sopenharmony_ci waiter->ops = &entries[i].waiter->ops; 71c72fcc34Sopenharmony_ci 72c72fcc34Sopenharmony_ci waiter->pfds = calloc(pfd_count, sizeof(*waiter->pfds)); 73c72fcc34Sopenharmony_ci if (waiter->pfds == NULL) 74c72fcc34Sopenharmony_ci return -ENOMEM; 75c72fcc34Sopenharmony_ci waiter->pfd_count = pfd_count; 76c72fcc34Sopenharmony_ci 77c72fcc34Sopenharmony_ci return 0; 78c72fcc34Sopenharmony_ci} 79c72fcc34Sopenharmony_ci 80c72fcc34Sopenharmony_ciint waiter_context_prepare(struct waiter_context *waiter) 81c72fcc34Sopenharmony_ci{ 82c72fcc34Sopenharmony_ci return waiter->ops->prepare(waiter); 83c72fcc34Sopenharmony_ci} 84c72fcc34Sopenharmony_ci 85c72fcc34Sopenharmony_ciint waiter_context_wait_event(struct waiter_context *waiter, 86c72fcc34Sopenharmony_ci int timeout_msec) 87c72fcc34Sopenharmony_ci{ 88c72fcc34Sopenharmony_ci return waiter->ops->wait_event(waiter, timeout_msec); 89c72fcc34Sopenharmony_ci} 90c72fcc34Sopenharmony_ci 91c72fcc34Sopenharmony_civoid waiter_context_release(struct waiter_context *waiter) 92c72fcc34Sopenharmony_ci{ 93c72fcc34Sopenharmony_ci waiter->ops->release(waiter); 94c72fcc34Sopenharmony_ci} 95c72fcc34Sopenharmony_ci 96c72fcc34Sopenharmony_civoid waiter_context_destroy(struct waiter_context *waiter) 97c72fcc34Sopenharmony_ci{ 98c72fcc34Sopenharmony_ci if (waiter->pfds) 99c72fcc34Sopenharmony_ci free(waiter->pfds); 100c72fcc34Sopenharmony_ci waiter->pfd_count = 0; 101c72fcc34Sopenharmony_ci if (waiter->private_data) 102c72fcc34Sopenharmony_ci free(waiter->private_data); 103c72fcc34Sopenharmony_ci waiter->private_data = NULL; 104c72fcc34Sopenharmony_ci} 105