mirror of
https://git.proxmox.com/git/mirror_corosync
synced 2025-08-13 12:52:31 +00:00
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:
parent
101b05fea0
commit
9a1d1c0ec2
143
exec/aispoll.c
143
exec/aispoll.c
@ -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 */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 (
|
||||
|
Loading…
Reference in New Issue
Block a user