/*
- * Copyright (c) 1995, Index Data
+ * Copyright (c) 1995-1998, Index Data
* See the file LICENSE for details.
* Sebastian Hammer, Adam Dickmeiss
*
* $Log: eventl.c,v $
- * Revision 1.17 1995-11-07 12:37:44 quinn
+ * Revision 1.26 1998-02-11 11:53:35 adam
+ * Changed code so that it compiles as C++.
+ *
+ * Revision 1.25 1998/01/29 13:30:23 adam
+ * Better event handle system for NT/Unix.
+ *
+ * Revision 1.24 1997/09/04 14:19:13 adam
+ * Added credits.
+ *
+ * Revision 1.23 1997/09/01 08:52:59 adam
+ * New windows NT/95 port using MSV5.0. The test server 'ztest' was
+ * moved a separate directory. MSV5.0 project server.dsp created.
+ * As an option, the server can now operate as an NT service.
+ *
+ * Revision 1.22 1996/07/06 19:58:35 quinn
+ * System headerfiles gathered in yconfig
+ *
+ * Revision 1.21 1996/02/21 12:55:51 quinn
+ * small
+ *
+ * Revision 1.20 1996/02/21 12:52:55 quinn
+ * Test
+ *
+ * Revision 1.19 1995/12/05 11:17:30 quinn
+ * Moved some paranthesises around. Sigh.
+ *
+ * Revision 1.18 1995/11/13 09:27:41 quinn
+ * Fiddling with the variant stuff.
+ *
+ * Revision 1.17 1995/11/07 12:37:44 quinn
* Added support for forcing TIMEOUT event.
*
* Revision 1.16 1995/11/01 13:54:56 quinn
*
*/
+#include <yconfig.h>
#include <stdio.h>
#include <assert.h>
-#include <sys/time.h>
-#include <sys/types.h>
+#ifdef WINDOWS
+#include <winsock.h>
+#else
#include <unistd.h>
+#endif
#include <stdlib.h>
#include <errno.h>
#include <string.h>
-#ifdef _AIX
-#include <sys/select.h>
-#endif
-
-#include <eventl.h>
+#include <log.h>
+#include <comstack.h>
#include <xmalloc.h>
-
-static IOCHAN iochans = 0;
-
-IOCHAN iochan_getchan(void)
-{
- return iochans;
-}
+#include "eventl.h"
+#include "session.h"
+#include <statserv.h>
IOCHAN iochan_create(int fd, IOC_CALLBACK cb, int flags)
{
- IOCHAN new;
+ IOCHAN new_iochan;
- if (!(new = xmalloc(sizeof(*new))))
+ if (!(new_iochan = (IOCHAN)xmalloc(sizeof(*new_iochan))))
return 0;
- new->destroyed = 0;
- new->fd = fd;
- new->flags = flags;
- new->fun = cb;
- new->next = iochans;
- new->force_event = 0;
- new->last_event = new->max_idle = 0;
- iochans = new;
- return new;
+ new_iochan->destroyed = 0;
+ new_iochan->fd = fd;
+ new_iochan->flags = flags;
+ new_iochan->fun = cb;
+ new_iochan->force_event = 0;
+ new_iochan->last_event = new_iochan->max_idle = 0;
+ new_iochan->next = NULL;
+ return new_iochan;
}
-int event_loop()
+int event_loop(IOCHAN *iochans)
{
- do
+ do /* loop as long as there are active associations to process */
{
IOCHAN p, nextp;
fd_set in, out, except;
to.tv_sec = 5*60;
to.tv_usec = 0;
max = 0;
- for (p = iochans; p; p = p->next)
+ for (p = *iochans; p; p = p->next)
{
if (p->force_event)
- timeout = &nullto; /* polling select */
+ timeout = &nullto; /* polling select */
if (p->flags & EVENT_INPUT)
- FD_SET(p->fd, &in);
+ FD_SET(p->fd, &in);
if (p->flags & EVENT_OUTPUT)
- FD_SET(p->fd, &out);
+ FD_SET(p->fd, &out);
if (p->flags & EVENT_EXCEPT)
- FD_SET(p->fd, &except);
+ FD_SET(p->fd, &except);
if (p->fd > max)
- max = p->fd;
+ max = p->fd;
}
if ((res = select(max + 1, &in, &out, &except, timeout)) < 0)
{
if (errno == EINTR)
- continue;
- return 1;
+ continue;
+ else
+ {
+ /* Destroy the first member in the chain, and try again */
+ association *assoc = (association *)iochan_getdata(*iochans);
+ COMSTACK conn = assoc->client_link;
+
+ cs_close(conn);
+ destroy_association(assoc);
+ iochan_destroy(*iochans);
+ logf(LOG_DEBUG, "error while selecting, destroying iochan %p",
+ *iochans);
+ }
}
- for (p = iochans; p; p = p->next)
+ for (p = *iochans; p; p = p->next)
{
int force_event = p->force_event;
time_t now = time(0);
p->force_event = 0;
- if (FD_ISSET(p->fd, &in) || force_event == EVENT_INPUT)
+ if (!p->destroyed && (FD_ISSET(p->fd, &in) ||
+ force_event == EVENT_INPUT))
{
- p->last_event = now;
- (*p->fun)(p, EVENT_INPUT);
+ p->last_event = now;
+ (*p->fun)(p, EVENT_INPUT);
}
if (!p->destroyed && (FD_ISSET(p->fd, &out) ||
- force_event == EVENT_OUTPUT))
+ force_event == EVENT_OUTPUT))
{
- p->last_event = now;
+ p->last_event = now;
(*p->fun)(p, EVENT_OUTPUT);
}
if (!p->destroyed && (FD_ISSET(p->fd, &except) ||
- force_event == EVENT_EXCEPT))
+ force_event == EVENT_EXCEPT))
{
p->last_event = now;
(*p->fun)(p, EVENT_EXCEPT);
}
- if (!p->destroyed && (p->max_idle && now - p->last_event >
- p->max_idle) || force_event == EVENT_TIMEOUT)
+ if (!p->destroyed && ((p->max_idle && now - p->last_event >
+ p->max_idle) || force_event == EVENT_TIMEOUT))
{
- p->last_event = now;
- (*p->fun)(p, EVENT_TIMEOUT);
+ p->last_event = now;
+ (*p->fun)(p, EVENT_TIMEOUT);
}
}
- for (p = iochans; p; p = nextp)
+ for (p = *iochans; p; p = nextp)
{
nextp = p->next;
if (p->destroyed)
{
- IOCHAN tmp = p, pr;
+ IOCHAN tmp = p, pr;
+
+ /* We need to inform the threadlist that this channel has been destroyed */
+ statserv_remove(p);
- if (p == iochans)
- iochans = p->next;
+ /* Now reset the pointers */
+ if (p == *iochans)
+ *iochans = p->next;
else
{
- for (pr = iochans; pr; pr = pr->next)
- if (pr->next == p)
- break;
+ for (pr = *iochans; pr; pr = pr->next)
+ if (pr->next == p)
+ break;
assert(pr); /* grave error if it weren't there */
pr->next = p->next;
}
}
}
}
- while (iochans);
+ while (*iochans);
return 0;
}