Commit 83ae5ab9 authored by Pekka Pessi's avatar Pekka Pessi

su: initial support for epoll in su_root_t/su_port_t.

darcs-hash:20060929131355-65a35-3d3df5d242ac6cbb4b02cd8a06ec89bdd2598ed5.gz
parent e7099da8
......@@ -79,6 +79,9 @@ SOFIA_BEGIN_DECLS
/** Initializer for a wait object. @HI */
#define SU_WAIT_INIT { INVALID_SOCKET, 0, 0 }
/** Maximum number of sources supported by su_wait() */
#define SU_WAIT_MAX (0x7fffffff)
#elif SU_HAVE_WINSOCK
#define SU_WAIT_CMP(x, y) ((intptr_t)(x) - (intptr_t)(y))
......@@ -95,6 +98,8 @@ SOFIA_BEGIN_DECLS
#define SU_WAIT_INIT NULL
#define SU_WAIT_MAX (64)
#else
#define SU_WAIT_CMP(x, y)
#define SU_WAIT_IN
......@@ -362,6 +367,7 @@ SOFIAPUBFUN su_root_magic_t *su_root_magic(su_root_t *root);
SOFIAPUBFUN int su_root_register(su_root_t*, su_wait_t *,
su_wakeup_f, su_wakeup_arg_t *,
int priority);
/* This is slow. Deprecated. */
SOFIAPUBFUN int su_root_unregister(su_root_t*, su_wait_t *,
su_wakeup_f, su_wakeup_arg_t*);
SOFIAPUBFUN int su_root_deregister(su_root_t*, int);
......
......@@ -815,8 +815,8 @@ int su_port_osx_register(su_port_t *self,
else
size = 2 * self->sup_size_waits;
if (size < SU_MIN_WAITS)
size = SU_MIN_WAITS;
if (size < SU_WAIT_MIN)
size = SU_WAIT_MIN;
/* Too large */
if (-3 - size > 0)
......
This diff is collapsed.
......@@ -55,17 +55,9 @@
#include <assert.h>
SOFIA_BEGIN_DECLS
/* Minimum array size (size of su_waits, sur_wait_cbs, sur_wait_args) */
#define SU_MIN_WAITS (16)
#define SU_WAIT_MIN (16)
#if SU_HAVE_WINSOCK
#define SU_MAX_WAITS (64)
#elif SU_HAVE_POLL
/* This may be even bigger on some OSs */
#define SU_MAX_WAITS (1024)
#endif
SOFIA_BEGIN_DECLS
/** Message */
struct su_msg_s {
......
......@@ -255,12 +255,16 @@ do_exit(struct pinger *x, su_timer_t *t, void *x0)
int
do_init(su_root_t *root, struct pinger *p)
{
su_wait_t w, w0;
su_wait_t w;
su_socket_t s;
long interval;
su_timer_t *t;
su_wakeup_f f;
int index, index0;
int index;
#if nomore
su_wait_t w0;
int index0
#endif
switch (p->sort) {
case PINGER: f = do_rtt; interval = 200; break;
......@@ -277,6 +281,8 @@ do_init(su_root_t *root, struct pinger *p)
/* Create a sockets, */
p->s = s = udpsocket();
#if nomore
if (su_wait_create(&w0, s, SU_WAIT_IN) == SOCKET_ERROR) {
su_perror("su_wait_create");
return SU_FAILURE;
......@@ -287,6 +293,7 @@ do_init(su_root_t *root, struct pinger *p)
su_perror("su_root_register");
return SU_FAILURE;
}
#endif
if (su_wait_create(&w, s, SU_WAIT_IN) == SOCKET_ERROR) {
su_perror("su_wait_create");
......@@ -299,8 +306,9 @@ do_init(su_root_t *root, struct pinger *p)
return SU_FAILURE;
}
#if nomore
su_root_deregister(root, index0);
#endif
p->rindex = index;
return 0;
......
......@@ -32,6 +32,10 @@
#include "config.h"
struct su_root_magic_s;
#define SU_ROOT_MAGIC_T struct su_root_magic_s
#include "su_port.c"
#if HAVE_FUNC
......@@ -50,39 +54,106 @@ int tstflags;
char const *name = "torture_su_port";
static int callback(su_root_magic_t *magic,
su_wait_t *w,
su_wakeup_arg_t *arg)
{
return 0;
}
int const N0 = SU_HAVE_MBOX, N = 16, I = 17;
int test_sup_indices(su_port_t const *port)
{
int i, n = 0;
int i, n;
int *indices = port->sup_indices;
int *reverses = port->sup_reverses;
int N = port->sup_size_waits;
if (indices == NULL)
return N == 0 && port->sup_n_waits == 0;
for (i = 0; i < port->sup_size_waits; i++) {
if (port->sup_indices[i] >= 0) {
if (port->sup_reverses[port->sup_indices[i]] != i)
for (i = 0, n = 0; i < N; i++) {
if (reverses[i] > 0) {
if (indices[reverses[i]] != i)
return 0;
n++;
}
}
for (i = port->sup_free_index; i != -1; i = port->sup_indices[i]) {
if (i >= 0)
return 0;
if (n != port->sup_n_waits)
return 0;
n = 0;
n++;
i = -2 - i;
for (i = 1; i <= N; i++) {
if (indices[i] >= 0) {
if (reverses[indices[i]] != i)
return 0;
n++;
}
}
if (n != port->sup_n_waits)
return 0;
if (i >= port->sup_size_waits)
for (i = indices[0]; -i <= N; i = indices[-i]) {
if (i >= 0)
return 0;
n++;
}
return n == port->sup_size_waits;
}
struct su_root_magic_s
{
int error, *sockets, *regs, *wakeups;
};
static int callback(su_root_magic_t *magic,
su_wait_t *w,
su_wakeup_arg_t *arg)
{
int i = (int)arg;
assert(magic);
if (i < 0 || i > 16)
return ++magic->error;
magic->wakeups[i]++;
#if HAVE_POLL
if (w->fd != magic->sockets[i])
return ++magic->error;
#endif
return 0;
}
int test_wakeup(su_port_t *port, su_root_magic_t *magic)
{
int i;
for (i = N0; i < N; i++) {
su_sockaddr_t su[1]; socklen_t sulen = sizeof su;
int n, woken = magic->wakeups[i];
char buf[1];
if (magic->regs[i] == 0)
continue;
if (getsockname(magic->sockets[i], &su->su_sa, &sulen) < 0)
su_perror("getsockname"), exit(1);
if (su_sendto(magic->sockets[1], "X", 1, 0, &su->su_sa, sulen) < 0)
su_perror("su_sendto"), exit(1);
n = su_port_wait_events(port, 100);
if (n != 1)
return 1;
if (magic->error)
return 2;
if (magic->wakeups[i] != woken + 1)
return 3;
if (recv(magic->sockets[i], buf, 1, 0) != 1)
return 4;
}
return 0;
}
int test_register(void)
{
su_port_t *port;
......@@ -90,7 +161,10 @@ int test_register(void)
int i;
int sockets[32] = { 0 };
int reg[32] = { 0 };
int wakeups[32] = { 0 };
su_wait_t wait[32];
su_root_magic_t magic[1] = {{ 0, sockets, reg, wakeups }};
su_root_t root[1] = {{ sizeof root, magic }};
BEGIN();
......@@ -100,6 +174,10 @@ int test_register(void)
memset(wait, 0, sizeof wait);
memset(sockets, -1, sizeof sockets);
memset(reg, 0, sizeof reg);
memset(wakeups, 0, sizeof wakeups);
su_root_size_hint = 16;
TEST_1(port = su_port_create());
......@@ -108,36 +186,61 @@ int test_register(void)
TEST_1(test_sup_indices(port));
for (i = 1; i < 16 + !SU_HAVE_MBOX; i++) {
for (i = N0; i < N; i++) {
sockets[i] = su_socket(AF_INET, SOCK_DGRAM, 0); TEST_1(sockets[i] != -1);
TEST(bind(sockets[i], &su->su_sa, sizeof su->su_sin), 0);
TEST(su_wait_create(wait + i, sockets[i], SU_WAIT_IN), 0);
reg[i] = su_port_register(port, NULL, wait + i, callback, port, 0);
reg[i] = su_port_register(port, root, wait + i, callback, (void*)i, 0);
TEST_1(reg[i] > 0);
}
TEST(port->sup_free_index, -1);
TEST(port->sup_indices[0], -I);
TEST_1(test_sup_indices(port));
TEST(test_wakeup(port, magic), 0);
for (i = 1; i < 16; i += 2) {
for (i = 1; i < N; i += 2) {
TEST(su_port_deregister(port, reg[i]), reg[i]);
TEST_1(test_sup_indices(port));
}
TEST_1(test_sup_indices(port));
for (i = 15; i > 0; i -= 2) {
for (i = N - 1; i >= N0; i -= 2) {
TEST(su_wait_create(wait + i, sockets[i], SU_WAIT_IN), 0);
reg[i] = su_port_register(port, NULL, wait + i, callback, port, 1);
reg[i] = su_port_register(port, root, wait + i, callback, (void *)i, 1);
TEST_1(reg[i] > 0);
#if HAVE_EPOLL
/* With epoll we do not bother to prioritize the wait list */
if (port->sup_epoll != -1) {
int N = port->sup_n_waits;
TEST_M(wait + i, port->sup_waits + N - 1, sizeof wait[0]);
}
else
#endif
TEST_M(wait + i, port->sup_waits, sizeof wait[0]);
}
TEST(port->sup_free_index, -1);
TEST(port->sup_indices[0], -I);
#if HAVE_EPOLL
/* With epoll we do not bother to prioritize the wait list */
if (port->sup_epoll != -1) {
TEST_M(wait + 15, port->sup_waits + 8, sizeof wait[0]);
TEST_M(wait + 13, port->sup_waits + 9, sizeof wait[0]);
TEST_M(wait + 11, port->sup_waits + 10, sizeof wait[0]);
TEST_M(wait + 9, port->sup_waits + 11, sizeof wait[0]);
TEST_M(wait + 7, port->sup_waits + 12, sizeof wait[0]);
TEST_M(wait + 5, port->sup_waits + 13, sizeof wait[0]);
TEST_M(wait + 3, port->sup_waits + 14, sizeof wait[0]);
TEST_M(wait + 1, port->sup_waits + 15, sizeof wait[0]);
}
else
#endif
{
TEST_M(wait + 15, port->sup_waits + 7, sizeof wait[0]);
TEST_M(wait + 13, port->sup_waits + 6, sizeof wait[0]);
TEST_M(wait + 11, port->sup_waits + 5, sizeof wait[0]);
......@@ -146,14 +249,20 @@ int test_register(void)
TEST_M(wait + 5, port->sup_waits + 2, sizeof wait[0]);
TEST_M(wait + 3, port->sup_waits + 1, sizeof wait[0]);
TEST_M(wait + 1, port->sup_waits + 0, sizeof wait[0]);
}
TEST_1(test_sup_indices(port));
TEST(test_wakeup(port, magic), 0);
for (i = 1; i <= 8; i++) {
TEST(su_port_deregister(port, reg[i]), reg[i]);
TEST(su_port_deregister(port, reg[i]), reg[i]); reg[i] = 0;
}
TEST(port->sup_pri_offset, 4);
#if HAVE_EPOLL
/* With epoll we do not bother to prioritize the wait list */
if (port->sup_epoll == -1)
#endif
TEST(port->sup_pri_offset, 4);
TEST_1(test_sup_indices(port));
......
......@@ -203,7 +203,7 @@ static int register_test(root_test_t *rt)
rt->rt_ep[i]->registered =
su_root_register(rt->rt_root, rt->rt_ep[i]->wait,
wakeups[i], rt->rt_ep[i], 0);
TEST(rt->rt_ep[i]->registered, i + 1);
TEST(rt->rt_ep[i]->registered, i + 1 + SU_HAVE_PTHREADS);
}
for (i = 0; i < 5; i++) {
......@@ -217,7 +217,8 @@ static int register_test(root_test_t *rt)
for (i = 0; i < 5; i++) {
TEST(su_root_unregister(rt->rt_root, rt->rt_ep[i]->wait,
wakeups[i], rt->rt_ep[i]), i + 1);
wakeups[i], rt->rt_ep[i]),
rt->rt_ep[i]->registered);
}
......
......@@ -451,14 +451,19 @@ AC_SEARCH_LIBS(getaddrinfo, xnet socket nsl)
AC_CHECK_FUNCS([gettimeofday strerror random initstate tcsetattr flock alarm \
socketpair gethostname gethostbyname getipnodebyname \
poll epoll select if_nameindex \
poll epoll_create select if_nameindex \
getaddrinfo getnameinfo freeaddrinfo gai_strerror getifaddrs \
getline getdelim getpass])
# getline getdelim getpass are _GNU_SOURCE stuff
if test $ac_cv_func_poll = yes ; then
SAC_SU_DEFINE([SU_HAVE_POLL], 1, [Define to 1 if you have poll().])
fi
if test $ac_cv_func_epoll_create = yes ; then
AC_DEFINE([HAVE_EPOLL], 1, [Define to 1 if you have epoll interface.])
fi
if test $ac_cv_func_if_nameindex = yes ; then
SAC_SU_DEFINE([SU_HAVE_IF_NAMEINDEX], 1,
[Define to 1 if you have if_nameindex().])
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment