poll: Add internal API for IO Conditions

This is needed to support busses other than USB.
This commit is contained in:
Benjamin Berg 2019-06-10 16:48:38 +02:00
parent afe5e1ad4c
commit 12748d348b
2 changed files with 125 additions and 0 deletions

View file

@ -28,6 +28,7 @@
#include <sys/time.h>
#include <glib.h>
#include <glib-unix.h>
#include <libusb.h>
/**
@ -174,6 +175,100 @@ fpi_timeout_cancel(fpi_timeout *timeout)
g_source_destroy (timeout->source);
}
struct fpi_io_condition {
fpi_io_condition_fn callback;
int fd;
struct fp_dev *dev;
void *data;
GSource *source;
};
static gboolean
fpi_io_condition_wrapper_cb (int fd, GIOCondition cond, gpointer data)
{
fpi_io_condition *io_cond = data;
short events = 0;
if (cond & G_IO_IN)
events |= POLL_IN;
if (cond & G_IO_OUT)
events |= POLL_OUT;
if (cond & G_IO_PRI)
events |= POLL_PRI;
if (cond & G_IO_ERR)
events |= POLL_ERR;
if (cond & G_IO_HUP)
events |= POLL_HUP;
io_cond->callback (io_cond->dev, fd, cond, io_cond->data);
return G_SOURCE_CONTINUE;
}
static void
fpi_io_condition_destroy (gpointer data)
{
fpi_io_condition *io_cond = data;
if (fd_removed_cb)
fd_removed_cb(io_cond->fd);
g_free (io_cond);
}
fpi_io_condition *
fpi_io_condition_add(int fd,
short int events,
fpi_io_condition_fn callback,
struct fp_dev *dev,
void *data)
{
fpi_io_condition *io_cond;
GIOCondition cond = 0;
if (events & POLL_IN)
cond |= G_IO_IN;
if (events & POLL_OUT)
cond |= G_IO_OUT;
if (events & POLL_PRI)
cond |= G_IO_PRI;
if (events & POLL_ERR)
cond |= G_IO_ERR;
if (events & POLL_HUP)
cond |= G_IO_HUP;
io_cond = g_new0 (fpi_io_condition, 1);
io_cond->source = g_unix_fd_source_new (fd, cond);
io_cond->fd = fd;
io_cond->callback = callback;
io_cond->data = data;
io_cond->dev = dev;
g_source_set_callback (io_cond->source,
G_SOURCE_FUNC (fpi_io_condition_wrapper_cb),
io_cond,
fpi_io_condition_destroy);
g_source_attach (io_cond->source, fpi_main_ctx);
if (fd_added_cb)
fd_added_cb(fd, events);
return io_cond;
}
void
fpi_io_condition_set_name(fpi_io_condition *io_cond,
const char *name)
{
g_source_set_name (io_cond->source, name);
}
void
fpi_io_condition_remove(fpi_io_condition *io_cond)
{
g_source_destroy(io_cond->source);
}
static gboolean
dummy_cb (gpointer user_data)
{

View file

@ -48,4 +48,34 @@ void fpi_timeout_set_name(fpi_timeout *timeout,
const char *name);
void fpi_timeout_cancel(fpi_timeout *timeout);
/**
* fpi_io_condition_fn:
* @dev: the struct #fp_dev passed to fpi_io_condition_add()
* @fd: the registered file descriptor
* @events: The events that poll returend for the descriptor
* @data: the data passed to fpi_io_condition_add()
*
* The prototype of the callback function for fpi_io_condition_add().
* Note that structure will be free'ed when unregistering the condition.
*/
typedef void (*fpi_io_condition_fn)(struct fp_dev *dev, int fd, short int events, void *data);
/**
* fpi_io_cond:
*
* An opaque structure representing a pollable file descriptor and a
* callback function created with fpi_io_condition_add().
*/
typedef struct fpi_io_condition fpi_io_condition;
fpi_io_condition *fpi_io_condition_add(int fd,
short int events,
fpi_io_condition_fn callback,
struct fp_dev *dev,
void *data);
void fpi_io_condition_set_name(fpi_io_condition *io_cond,
const char *name);
void fpi_io_condition_remove(fpi_io_condition *io_cond);
#endif