Linux Audio

Check our new training course

Real-Time Linux with PREEMPT_RT training

Feb 18-20, 2025
Register
Loading...
Note: File does not exist in v4.6.
  1// SPDX-License-Identifier: LGPL-2.1+
  2// Copyright (C) 2022, Linaro Ltd - Daniel Lezcano <daniel.lezcano@linaro.org>
  3#include <stdlib.h>
  4#include <errno.h>
  5#include <unistd.h>
  6#include <signal.h>
  7#include <sys/epoll.h>
  8#include "mainloop.h"
  9#include "log.h"
 10
 11static int epfd = -1;
 12static sig_atomic_t exit_mainloop;
 13
 14struct mainloop_data {
 15	mainloop_callback_t cb;
 16	void *data;
 17	int fd;
 18};
 19
 20#define MAX_EVENTS 10
 21
 22int mainloop(unsigned int timeout)
 23{
 24	int i, nfds;
 25	struct epoll_event events[MAX_EVENTS];
 26	struct mainloop_data *md;
 27
 28	if (epfd < 0)
 29		return -1;
 30
 31	for (;;) {
 32
 33		nfds = epoll_wait(epfd, events, MAX_EVENTS, timeout);
 34
 35		if (exit_mainloop || !nfds)
 36			return 0;
 37
 38		if (nfds < 0) {
 39			if (errno == EINTR)
 40				continue;
 41			return -1;
 42		}
 43
 44		for (i = 0; i < nfds; i++) {
 45			md = events[i].data.ptr;
 46
 47			if (md->cb(md->fd, md->data) > 0)
 48				return 0;
 49		}
 50	}
 51}
 52
 53int mainloop_add(int fd, mainloop_callback_t cb, void *data)
 54{
 55	struct epoll_event ev = {
 56		.events = EPOLLIN,
 57	};
 58
 59	struct mainloop_data *md;
 60
 61	md = malloc(sizeof(*md));
 62	if (!md)
 63		return -1;
 64
 65	md->data = data;
 66	md->cb = cb;
 67	md->fd = fd;
 68
 69	ev.data.ptr = md;
 70
 71	if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev) < 0) {
 72		free(md);
 73		return -1;
 74	}
 75
 76	return 0;
 77}
 78
 79int mainloop_del(int fd)
 80{
 81	if (epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL) < 0)
 82		return -1;
 83
 84	return 0;
 85}
 86
 87int mainloop_init(void)
 88{
 89	epfd = epoll_create(2);
 90	if (epfd < 0)
 91		return -1;
 92
 93	return 0;
 94}
 95
 96void mainloop_exit(void)
 97{
 98	exit_mainloop = 1;
 99}
100
101void mainloop_fini(void)
102{
103	close(epfd);
104}