From 6ca781b8a38474ab428d5fcb3b489dfe3e974334 Mon Sep 17 00:00:00 2001 From: bustico Date: Fri, 21 Mar 2008 09:03:34 +0000 Subject: - numerous fixes - socket in non blocking mode (resolve some deadlock, and agent are immune to another agent beeing blocked) --- src/ivyloop.c | 245 ++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 142 insertions(+), 103 deletions(-) (limited to 'src/ivyloop.c') diff --git a/src/ivyloop.c b/src/ivyloop.c index 3d1008c..70a1938 100644 --- a/src/ivyloop.c +++ b/src/ivyloop.c @@ -41,12 +41,13 @@ #include "timer.h" struct _channel { - Channel next; - HANDLE fd; - void *data; - int tobedeleted; - ChannelHandleDelete handle_delete; - ChannelHandleRead handle_read; + Channel next; + HANDLE fd; + void *data; + int tobedeleted; + ChannelHandleDelete handle_delete; + ChannelHandleRead handle_read; + ChannelHandleWrite handle_write; }; static Channel channels_list = NULL; @@ -54,6 +55,9 @@ static Channel channels_list = NULL; static int channel_initialized = 0; static fd_set open_fds; +static fd_set wrdy_fds; +static HANDLE highestFd=0; + static int MainLoop = 1; /* Hook callback & data */ @@ -70,167 +74,202 @@ WSADATA WsaData; void IvyChannelRemove (Channel channel) { - channel->tobedeleted = 1; + channel->tobedeleted = 1; } static void IvyChannelDelete (Channel channel) { - if (channel->handle_delete) - (*channel->handle_delete) (channel->data); + if (channel->handle_delete) + (*channel->handle_delete) (channel->data); - FD_CLR (channel->fd, &open_fds); - IVY_LIST_REMOVE (channels_list, channel); + FD_CLR (channel->fd, &open_fds); + FD_CLR (channel->fd, &wrdy_fds); + IVY_LIST_REMOVE (channels_list, channel); } static void ChannelDefferedDelete () { - Channel channel, next; - IVY_LIST_EACH_SAFE (channels_list, channel,next) { - if (channel->tobedeleted ) { - IvyChannelDelete (channel); - } - } + Channel channel, next; + IVY_LIST_EACH_SAFE (channels_list, channel,next) { + if (channel->tobedeleted ) { + IvyChannelDelete (channel); + } + } } Channel IvyChannelAdd (HANDLE fd, void *data, - ChannelHandleDelete handle_delete, - ChannelHandleRead handle_read - ) + ChannelHandleDelete handle_delete, + ChannelHandleRead handle_read, + ChannelHandleWrite handle_write + ) { - Channel channel; - - IVY_LIST_ADD_START (channels_list, channel) - channel->fd = fd; - channel->tobedeleted = 0; - channel->handle_delete = handle_delete; - channel->handle_read = handle_read; - channel->data = data; - IVY_LIST_ADD_END (channels_list, channel) - - FD_SET (channel->fd, &open_fds); + Channel channel; + + + IVY_LIST_ADD_START (channels_list, channel) + channel->fd = fd; + channel->tobedeleted = 0; + channel->handle_delete = handle_delete; + channel->handle_read = handle_read; + channel->handle_write = handle_write; + channel->data = data; + if (channel->fd >= highestFd) + highestFd = channel->fd+1 ; + + IVY_LIST_ADD_END (channels_list, channel) + + FD_SET (channel->fd, &open_fds); + + return channel; +} + +void IvyChannelAddWritableEvent(Channel channel) +{ + if (channel->fd >= highestFd) + highestFd = channel->fd+1 ; + + FD_SET (channel->fd, &wrdy_fds); +} - return channel; +void IvyChannelClearWritableEvent(Channel channel) +{ + FD_CLR (channel->fd, &wrdy_fds); +} + +static void +IvyChannelHandleWrite (fd_set *current) +{ + Channel channel, next; + + IVY_LIST_EACH_SAFE (channels_list, channel, next) { + if (FD_ISSET (channel->fd, current)) { + (*channel->handle_write)(channel,channel->fd,channel->data); + } + } } static void IvyChannelHandleRead (fd_set *current) { - Channel channel, next; + Channel channel, next; - IVY_LIST_EACH_SAFE (channels_list, channel, next) { - if (FD_ISSET (channel->fd, current)) { - (*channel->handle_read)(channel,channel->fd,channel->data); - } - } + IVY_LIST_EACH_SAFE (channels_list, channel, next) { + if (FD_ISSET (channel->fd, current)) { + (*channel->handle_read)(channel,channel->fd,channel->data); + } + } } static void IvyChannelHandleExcpt (fd_set *current) { - Channel channel,next; - IVY_LIST_EACH_SAFE (channels_list, channel, next) { - if (FD_ISSET (channel->fd, current)) { - if (channel->handle_delete) - (*channel->handle_delete)(channel->data); -/* IvyChannelClose (channel); */ - } - } + Channel channel,next; + IVY_LIST_EACH_SAFE (channels_list, channel, next) { + if (FD_ISSET (channel->fd, current)) { + if (channel->handle_delete) + (*channel->handle_delete)(channel->data); + /* IvyChannelClose (channel); */ + } + } } void IvyChannelInit (void) { #ifdef WIN32 - int error; + int error; #else - /* pour eviter les plantages quand les autres applis font core-dump */ - signal (SIGPIPE, SIG_IGN); + /* pour eviter les plantages quand les autres applis font core-dump */ + signal (SIGPIPE, SIG_IGN); #endif - if (channel_initialized) return; + if (channel_initialized) return; - FD_ZERO (&open_fds); + FD_ZERO (&open_fds); + FD_ZERO (&wrdy_fds); #ifdef WIN32 - error = WSAStartup (0x0101, &WsaData); - if (error == SOCKET_ERROR) { - printf ("WSAStartup failed.\n"); - } + error = WSAStartup (0x0101, &WsaData); + if (error == SOCKET_ERROR) { + printf ("WSAStartup failed.\n"); + } #endif - channel_initialized = 1; + channel_initialized = 1; } void IvyChannelStop (void) { - MainLoop = 0; + MainLoop = 0; } void IvyMainLoop(void) { - fd_set rdset; - fd_set exset; - int ready; + fd_set rdset, exset, wrset; + int ready; - while (MainLoop) { + while (MainLoop) { - ChannelDefferedDelete(); + ChannelDefferedDelete(); - if (BeforeSelect) - (*BeforeSelect)(BeforeSelectData); - rdset = open_fds; - exset = open_fds; - ready = select(64, &rdset, 0, &exset, TimerGetSmallestTimeout()); + if (BeforeSelect) + (*BeforeSelect)(BeforeSelectData); + rdset = open_fds; + wrset = wrdy_fds; + exset = open_fds; + ready = select(highestFd, &rdset, &wrset, &exset, + TimerGetSmallestTimeout()); - if (AfterSelect) - (*AfterSelect)(AfterSelectData); + if (AfterSelect) + (*AfterSelect)(AfterSelectData); - if (ready < 0 && (errno != EINTR)) { - fprintf (stderr, "select error %d\n",errno); - perror("select"); - return; - } - TimerScan(); /* should be spliited in two part ( next timeout & callbacks */ - if (ready > 0) { - IvyChannelHandleExcpt(&exset); - IvyChannelHandleRead(&rdset); - } - } + if (ready < 0 && (errno != EINTR)) { + fprintf (stderr, "select error %d\n",errno); + perror("select"); + return; + } + TimerScan(); /* should be spliited in two part ( next timeout & callbacks */ + if (ready > 0) { + IvyChannelHandleExcpt(&exset); + IvyChannelHandleRead(&rdset); + IvyChannelHandleWrite(&wrset); + } + } } void IvyIdle() { - - fd_set rdset; - fd_set exset; - int ready; - struct timeval timeout = {0,0}; + fd_set rdset, exset, wrset; + int ready; + struct timeval timeout = {0,0}; - ChannelDefferedDelete(); - rdset = open_fds; - exset = open_fds; - ready = select(64, &rdset, 0, &exset, &timeout); - if (ready < 0 && (errno != EINTR)) { - fprintf (stderr, "select error %d\n",errno); - perror("select"); - return; - } - if (ready > 0) { - IvyChannelHandleExcpt(&exset); - IvyChannelHandleRead(&rdset); - } - + ChannelDefferedDelete(); + rdset = open_fds; + wrset = wrdy_fds; + exset = open_fds; + ready = select(highestFd, &rdset, &wrset, &exset, &timeout); + if (ready < 0 && (errno != EINTR)) { + fprintf (stderr, "select error %d\n",errno); + perror("select"); + return; + } + if (ready > 0) { + IvyChannelHandleExcpt(&exset); + IvyChannelHandleRead(&rdset); + IvyChannelHandleWrite(&wrset); + } } + void IvySetBeforeSelectHook(IvyHookPtr before, void *data ) { - BeforeSelect = before; - BeforeSelectData = data; + BeforeSelect = before; + BeforeSelectData = data; } void IvySetAfterSelectHook(IvyHookPtr after, void *data ) { - AfterSelect = after; - AfterSelectData = data; + AfterSelect = after; + AfterSelectData = data; } -- cgit v1.1