/*
* melisma - extensible and scriptable audio engine
* Copyright (C) 2026 Ludvig Gunne Lindström
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include
#include "io.h"
#include "mem.h"
struct io
{
ml_io_handler hdl;
void *args;
bool removed;
};
static struct io *ios;
static struct pollfd *pollfds;
static size_t num_fds;
void ml_add_io_handler(int fd, int flags, ml_io_handler hdl, void *args)
{
size_t i = num_fds++;
ios = srealloc(ios,sizeof(*ios)*num_fds);
pollfds = srealloc(pollfds,sizeof(*pollfds)*num_fds);
ios[i] = (struct io) {
.hdl = hdl,
.args = args,
};
pollfds[i] = (struct pollfd) {
.fd = fd,
.events = flags,
};
}
void ml_remove_io_handler(int fd)
{
for (size_t i = 0; i < num_fds; i++)
{
if (pollfds[i].fd == fd)
{
ios[i].removed = true;
return;
}
}
}
static bool remove_fds(void)
{
for (size_t i = 0; i < num_fds; i++)
{
if (ios[i].removed)
{
num_fds--;
ios[i] = ios[num_fds];
pollfds[i] = pollfds[num_fds];
return true;
}
}
return false;
}
void io_loop(void)
{
while (poll(pollfds,num_fds,-1) >= 0)
{
for (size_t i = 0; i < num_fds; i++)
{
struct pollfd *p = &pollfds[i];
struct io *io = &ios[i];
if ((p->revents & p->events) && io->hdl)
{
io->hdl(p->fd,p->revents,io->args);
}
}
while (remove_fds())
;
}
}