cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mainloop.c (1781B)


      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 unsigned short nrhandler;
     13static sig_atomic_t exit_mainloop;
     14
     15struct mainloop_data {
     16	mainloop_callback_t cb;
     17	void *data;
     18	int fd;
     19};
     20
     21static struct mainloop_data **mds;
     22
     23#define MAX_EVENTS 10
     24
     25int mainloop(unsigned int timeout)
     26{
     27	int i, nfds;
     28	struct epoll_event events[MAX_EVENTS];
     29	struct mainloop_data *md;
     30
     31	if (epfd < 0)
     32		return -1;
     33
     34	for (;;) {
     35
     36		nfds = epoll_wait(epfd, events, MAX_EVENTS, timeout);
     37
     38		if (exit_mainloop || !nfds)
     39			return 0;
     40
     41		if (nfds < 0) {
     42			if (errno == EINTR)
     43				continue;
     44			return -1;
     45		}
     46
     47		for (i = 0; i < nfds; i++) {
     48			md = events[i].data.ptr;
     49
     50			if (md->cb(md->fd, md->data) > 0)
     51				return 0;
     52		}
     53	}
     54}
     55
     56int mainloop_add(int fd, mainloop_callback_t cb, void *data)
     57{
     58	struct epoll_event ev = {
     59		.events = EPOLLIN,
     60	};
     61
     62	struct mainloop_data *md;
     63
     64	if (fd >= nrhandler) {
     65		mds = realloc(mds, sizeof(*mds) * (fd + 1));
     66		if (!mds)
     67			return -1;
     68		nrhandler = fd + 1;
     69	}
     70
     71	md = malloc(sizeof(*md));
     72	if (!md)
     73		return -1;
     74
     75	md->data = data;
     76	md->cb = cb;
     77	md->fd = fd;
     78
     79	mds[fd] = md;
     80	ev.data.ptr = md;
     81
     82	if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev) < 0) {
     83		free(md);
     84		return -1;
     85	}
     86
     87	return 0;
     88}
     89
     90int mainloop_del(int fd)
     91{
     92	if (fd >= nrhandler)
     93		return -1;
     94
     95	if (epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL) < 0)
     96		return -1;
     97
     98	free(mds[fd]);
     99
    100	return 0;
    101}
    102
    103int mainloop_init(void)
    104{
    105	epfd = epoll_create(2);
    106	if (epfd < 0)
    107		return -1;
    108
    109	return 0;
    110}
    111
    112void mainloop_exit(void)
    113{
    114	exit_mainloop = 1;
    115}
    116
    117void mainloop_fini(void)
    118{
    119	close(epfd);
    120}