Add priority to poll abstraction

Higher priority items will be serviced first

(Logical change 1.54)


git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@172 fd59a12c-fef9-0310-b244-a6a79926bd2f
This commit is contained in:
Steven Dake 2004-08-14 09:25:33 +00:00
parent 101b05fea0
commit 9a1d1c0ec2
2 changed files with 84 additions and 65 deletions

View File

@ -43,13 +43,19 @@
#include "../include/ais_types.h"
#include "tlist.h"
typedef int (*dispatch_fn_t) (poll_handle poll_handle, int fd, int revents, void *data);
typedef int (*dispatch_fn_t) (poll_handle poll_handle, int fd, int revents, void *data, unsigned int *prio);
struct poll_entry {
unsigned int prio;
struct pollfd ufd;
dispatch_fn_t dispatch_fn;
void *data;
};
struct poll_instance {
struct poll_entry *poll_entries;
struct pollfd *ufds;
int nfds;
dispatch_fn_t *dispatch_fns;
void **data;
int poll_entry_count;
struct timerlist timerlist;
};
@ -79,10 +85,9 @@ poll_handle poll_create (void)
goto error_destroy;
}
poll_instance->poll_entries = 0;
poll_instance->ufds = 0;
poll_instance->nfds = 0;
poll_instance->dispatch_fns = 0;
poll_instance->data = 0;
poll_instance->poll_entry_count = 0;
timerlist_init (&poll_instance->timerlist);
return (handle);
@ -105,15 +110,12 @@ int poll_destroy (poll_handle handle)
goto error_exit;
}
if (poll_instance->poll_entries) {
free (poll_instance->poll_entries);
}
if (poll_instance->ufds) {
free (poll_instance->ufds);
}
if (poll_instance->dispatch_fns) {
free (poll_instance->dispatch_fns);
}
if (poll_instance->data) {
free (poll_instance->data);
}
timerlist_free (&poll_instance->timerlist);
saHandleDestroy (&poll_instance_database, handle);
@ -131,12 +133,12 @@ int poll_dispatch_add (
int fd,
int events,
void *data,
int (*dispatch_fn) (poll_handle poll_handle, int fd, int revents, void *data))
int (*dispatch_fn) (poll_handle poll_handle, int fd, int revents, void *data, unsigned int *prio),
unsigned int prio)
{
struct poll_instance *poll_instance;
struct poll_entry *poll_entries;
struct pollfd *ufds;
dispatch_fn_t *dispatch_fns;
void **data_list;
int found = 0;
int install_pos;
SaErrorT error;
@ -147,8 +149,8 @@ int poll_dispatch_add (
goto error_exit;
}
for (found = 0, install_pos = 0; install_pos < poll_instance->nfds; install_pos++) {
if (poll_instance->ufds[install_pos].fd == -1) {
for (found = 0, install_pos = 0; install_pos < poll_instance->poll_entry_count; install_pos++) {
if (poll_instance->poll_entries[install_pos].ufd.fd == -1) {
found = 1;
break;
}
@ -158,48 +160,37 @@ int poll_dispatch_add (
/*
* Grow pollfd list
*/
poll_entries = (struct poll_entry *)realloc (poll_instance->poll_entries,
(poll_instance->poll_entry_count + 1) *
sizeof (struct poll_entry));
if (poll_entries == 0) {
errno = ENOMEM;
goto error_exit;
}
poll_instance->poll_entries = poll_entries;
ufds = (struct pollfd *)realloc (poll_instance->ufds,
(poll_instance->nfds + 1) * sizeof (struct pollfd));
(poll_instance->poll_entry_count + 1) *
sizeof (struct pollfd));
if (ufds == 0) {
errno = ENOMEM;
goto error_exit;
}
poll_instance->ufds = ufds;
/*
* Grow dispatch functions list
*/
dispatch_fns = (dispatch_fn_t *)realloc (poll_instance->dispatch_fns,
(poll_instance->nfds + 1) * sizeof (dispatch_fn_t));
if (dispatch_fns == 0) {
errno = ENOMEM;
goto error_exit;
}
poll_instance->dispatch_fns = dispatch_fns;
/*
* Grow data list
*/
data_list = (void **)realloc (poll_instance->data,
(poll_instance->nfds + 1) * sizeof (void *));
if (data_list == 0) {
errno = ENOMEM;
goto error_exit;
}
poll_instance->data = data_list;
poll_instance->nfds += 1;
install_pos = poll_instance->nfds - 1;
poll_instance->poll_entry_count += 1;
install_pos = poll_instance->poll_entry_count - 1;
}
/*
* Install new dispatch handler
*/
poll_instance->ufds[install_pos].fd = fd;
poll_instance->ufds[install_pos].events = events;
poll_instance->ufds[install_pos].revents = 0;
poll_instance->dispatch_fns[install_pos] = dispatch_fn;
poll_instance->data[install_pos] = data;
poll_instance->poll_entries[install_pos].prio = prio;
poll_instance->poll_entries[install_pos].ufd.fd = fd;
poll_instance->poll_entries[install_pos].ufd.events = events;
poll_instance->poll_entries[install_pos].ufd.revents = 0;
poll_instance->poll_entries[install_pos].dispatch_fn = dispatch_fn;
poll_instance->poll_entries[install_pos].data = data;
saHandleInstancePut (&poll_instance_database, handle);
@ -213,7 +204,8 @@ int poll_dispatch_modify (
poll_handle handle,
int fd,
int events,
int (*dispatch_fn) (poll_handle poll_handle, int fd, int revents, void *data))
int (*dispatch_fn) (poll_handle poll_handle, int fd, int revents, void *data, unsigned int *prio),
unsigned int prio)
{
struct poll_instance *poll_instance;
int i;
@ -228,10 +220,11 @@ int poll_dispatch_modify (
/*
* Find file descriptor to modify events and dispatch function
*/
for (i = 0; i < poll_instance->nfds; i++) {
if (poll_instance->ufds[i].fd == fd) {
poll_instance->ufds[i].events = events;
poll_instance->dispatch_fns[i] = dispatch_fn;
for (i = 0; i < poll_instance->poll_entry_count; i++) {
if (poll_instance->poll_entries[i].ufd.fd == fd) {
poll_instance->poll_entries[i].ufd.events = events;
poll_instance->poll_entries[i].dispatch_fn = dispatch_fn;
poll_instance->poll_entries[i].prio = prio;
return (0);
}
}
@ -262,15 +255,15 @@ int poll_dispatch_delete (
/*
* Find dispatch fd to delete
*/
for (i = 0; i < poll_instance->nfds; i++) {
if (poll_instance->ufds[i].fd == fd) {
for (i = 0; i < poll_instance->poll_entry_count; i++) {
if (poll_instance->poll_entries[i].ufd.fd == fd) {
found = 1;
break;
}
}
if (found) {
poll_instance->ufds[i].fd = -1;
poll_instance->poll_entries[i].ufd.fd = -1;
saHandleInstancePut (&poll_instance_database, handle);
return (0);
}
@ -338,6 +331,14 @@ error_exit:
return (-1);
}
int poll_entry_compare (const void *a, const void *b) {
struct poll_entry *poll_entry_a = (struct poll_entry *)a;
struct poll_entry *poll_entry_b = (struct poll_entry *)b;
return (poll_entry_a->prio < poll_entry_b->prio);
}
int poll_run (
poll_handle handle)
{
@ -346,6 +347,7 @@ int poll_run (
int timeout = -1;
int res;
SaErrorT error;
int poll_entry_count;
error = saHandleInstanceGet (&poll_instance_database, handle,
(void *)&poll_instance);
@ -354,10 +356,22 @@ int poll_run (
}
for (;;) {
/*
* Sort the poll entries list highest priority to lowest priority
* Then build ufds structure for use with poll system call
*/
qsort (poll_instance->poll_entries, poll_instance->poll_entry_count,
sizeof (struct poll_entry), poll_entry_compare);
for (i = 0; i < poll_instance->poll_entry_count; i++) {
memcpy (&poll_instance->ufds[i],
&poll_instance->poll_entries[i].ufd,
sizeof (struct pollfd));
}
timeout = timerlist_timeout_msec (&poll_instance->timerlist);
retry_poll:
res = poll (poll_instance->ufds, poll_instance->nfds, timeout);
res = poll (poll_instance->ufds,
poll_instance->poll_entry_count, timeout);
if (errno == EINTR && res == -1) {
goto retry_poll;
} else
@ -365,19 +379,22 @@ retry_poll:
goto error_exit;
}
for (i = 0; i < poll_instance->nfds; i++) {
poll_entry_count = poll_instance->poll_entry_count;
for (i = 0; i < poll_entry_count; i++) {
if (poll_instance->ufds[i].fd != -1 &&
poll_instance->ufds[i].revents) {
res = poll_instance->dispatch_fns[i] (handle, poll_instance->ufds[i].fd,
poll_instance->ufds[i].revents, poll_instance->data[i]);
res = poll_instance->poll_entries[i].dispatch_fn (handle,
poll_instance->ufds[i].fd,
poll_instance->ufds[i].revents,
poll_instance->poll_entries[i].data,
&poll_instance->poll_entries[i].prio);
/*
* Remove dispatch functions that return -1
*/
if (res == -1) {
poll_instance->ufds[i].fd = -1; /* empty entry */
poll_instance->poll_entries[i].ufd.fd = -1; /* empty entry */
}
}
}

View File

@ -46,13 +46,15 @@ int poll_dispatch_add (
int fd,
int events,
void *data,
int (*dispatch_fn) (poll_handle handle, int fd, int revents, void *data));
int (*dispatch_fn) (poll_handle handle, int fd, int revents, void *data, unsigned int *prio),
unsigned int prio);
int poll_dispatch_modify (
poll_handle handle,
int fd,
int events,
int (*dispatch_fn) (poll_handle poll_handle, int fd, int revents, void *data));
int (*dispatch_fn) (poll_handle poll_handle, int fd, int revents, void *data, unsigned int *prio),
unsigned int prio);
int poll_dispatch_delete (