summaryrefslogtreecommitdiff
path: root/src/ivyloop.c
diff options
context:
space:
mode:
authorbustico2008-03-21 09:03:34 +0000
committerbustico2008-03-21 09:03:34 +0000
commit6ca781b8a38474ab428d5fcb3b489dfe3e974334 (patch)
tree8c8725c88c3fd031d632a9f2b1f7376d1cb3c75b /src/ivyloop.c
parent50236114f04a0050625bedee7c4c02b36b1213ae (diff)
downloadivy-c-6ca781b8a38474ab428d5fcb3b489dfe3e974334.zip
ivy-c-6ca781b8a38474ab428d5fcb3b489dfe3e974334.tar.gz
ivy-c-6ca781b8a38474ab428d5fcb3b489dfe3e974334.tar.bz2
ivy-c-6ca781b8a38474ab428d5fcb3b489dfe3e974334.tar.xz
- numerous fixes
- socket in non blocking mode (resolve some deadlock, and agent are immune to another agent beeing blocked)
Diffstat (limited to 'src/ivyloop.c')
-rw-r--r--src/ivyloop.c245
1 files changed, 142 insertions, 103 deletions
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;
}