Blame axfer/waiter.c

Packit Service a9274b
// SPDX-License-Identifier: GPL-2.0
Packit Service a9274b
//
Packit Service a9274b
// waiter.c - I/O event waiter.
Packit Service a9274b
//
Packit Service a9274b
// Copyright (c) 2018 Takashi Sakamoto <o-takashi@sakamocchi.jp>
Packit Service a9274b
//
Packit Service a9274b
// Licensed under the terms of the GNU General Public License, version 2.
Packit Service a9274b
Packit Service a9274b
#include "waiter.h"
Packit Service a9274b
Packit Service a9274b
#include <stdlib.h>
Packit Service a9274b
#include <string.h>
Packit Service a9274b
#include <errno.h>
Packit Service a9274b
Packit Service a9274b
#include "misc.h"
Packit Service a9274b
Packit Service a9274b
static const char *const waiter_type_labels[] = {
Packit Service a9274b
	[WAITER_TYPE_DEFAULT] = "default",
Packit Service a9274b
	[WAITER_TYPE_POLL] = "poll",
Packit Service a9274b
	[WAITER_TYPE_SELECT] = "select",
Packit Service a9274b
	[WAITER_TYPE_EPOLL] = "epoll",
Packit Service a9274b
};
Packit Service a9274b
Packit Service a9274b
enum waiter_type waiter_type_from_label(const char *label)
Packit Service a9274b
{
Packit Service a9274b
	int i;
Packit Service a9274b
Packit Service a9274b
	for (i = 0; i < ARRAY_SIZE(waiter_type_labels); ++i) {
Packit Service a9274b
		if (!strcmp(waiter_type_labels[i], label))
Packit Service a9274b
			return i;
Packit Service a9274b
	}
Packit Service a9274b
Packit Service a9274b
	return WAITER_TYPE_DEFAULT;
Packit Service a9274b
}
Packit Service a9274b
Packit Service a9274b
const char *waiter_label_from_type(enum waiter_type type)
Packit Service a9274b
{
Packit Service a9274b
	return waiter_type_labels[type];
Packit Service a9274b
}
Packit Service a9274b
Packit Service a9274b
int waiter_context_init(struct waiter_context *waiter,
Packit Service a9274b
			enum waiter_type type, unsigned int pfd_count)
Packit Service a9274b
{
Packit Service a9274b
	struct {
Packit Service a9274b
		enum waiter_type type;
Packit Service a9274b
		const struct waiter_data *waiter;
Packit Service a9274b
	} entries[] = {
Packit Service a9274b
		{WAITER_TYPE_POLL,	&waiter_poll},
Packit Service a9274b
		{WAITER_TYPE_SELECT,	&waiter_select},
Packit Service a9274b
		{WAITER_TYPE_EPOLL,	&waiter_epoll},
Packit Service a9274b
	};
Packit Service a9274b
	int i;
Packit Service a9274b
Packit Service a9274b
	if (pfd_count == 0)
Packit Service a9274b
		return -EINVAL;
Packit Service a9274b
Packit Service a9274b
	for (i = 0; i < ARRAY_SIZE(entries); ++i) {
Packit Service a9274b
		if (entries[i].type == type)
Packit Service a9274b
			break;
Packit Service a9274b
	}
Packit Service a9274b
	if (i == ARRAY_SIZE(entries))
Packit Service a9274b
		return -EINVAL;
Packit Service a9274b
Packit Service a9274b
	waiter->private_data = malloc(entries[i].waiter->private_size);
Packit Service a9274b
	if (waiter->private_data == NULL)
Packit Service a9274b
		return -ENOMEM;
Packit Service a9274b
	memset(waiter->private_data, 0, entries[i].waiter->private_size);
Packit Service a9274b
Packit Service a9274b
	waiter->type = type;
Packit Service a9274b
	waiter->ops = &entries[i].waiter->ops;
Packit Service a9274b
Packit Service a9274b
	waiter->pfds = calloc(pfd_count, sizeof(*waiter->pfds));
Packit Service a9274b
	if (waiter->pfds == NULL)
Packit Service a9274b
		return -ENOMEM;
Packit Service a9274b
	waiter->pfd_count = pfd_count;
Packit Service a9274b
Packit Service a9274b
	return 0;
Packit Service a9274b
}
Packit Service a9274b
Packit Service a9274b
int waiter_context_prepare(struct waiter_context *waiter)
Packit Service a9274b
{
Packit Service a9274b
	return waiter->ops->prepare(waiter);
Packit Service a9274b
}
Packit Service a9274b
Packit Service a9274b
int waiter_context_wait_event(struct waiter_context *waiter,
Packit Service a9274b
				int timeout_msec)
Packit Service a9274b
{
Packit Service a9274b
	return waiter->ops->wait_event(waiter, timeout_msec);
Packit Service a9274b
}
Packit Service a9274b
Packit Service a9274b
void waiter_context_release(struct waiter_context *waiter)
Packit Service a9274b
{
Packit Service a9274b
	waiter->ops->release(waiter);
Packit Service a9274b
}
Packit Service a9274b
Packit Service a9274b
void waiter_context_destroy(struct waiter_context *waiter)
Packit Service a9274b
{
Packit Service a9274b
	if (waiter->pfds)
Packit Service a9274b
		free(waiter->pfds);
Packit Service a9274b
	waiter->pfd_count = 0;
Packit Service a9274b
	if (waiter->private_data)
Packit Service a9274b
		free(waiter->private_data);
Packit Service a9274b
	waiter->private_data = NULL;
Packit Service a9274b
}