getting the paraz2 server host and port info from the HTTP request, and mirroring...
[pazpar2-moved-to-github.git] / src / eventl.c
1 /*
2  * ParaZ - a simple tool for harvesting performance data for parallel
3  * operations using Z39.50.
4  * Copyright (c) 2000-2004 Index Data ApS
5  * See LICENSE file for details.
6  */
7
8 /*
9  * $Id: eventl.c,v 1.3 2007-03-28 12:05:18 marc Exp $
10  * Based on revision YAZ' server/eventl.c 1.29.
11  */
12
13 #include <stdio.h>
14 #include <assert.h>
15
16 #if HAVE_CONFIG_H
17 #include <cconfig.h>
18 #endif
19
20
21 #include <stdlib.h>
22 #include <errno.h>
23 #include <string.h>
24
25 #include <yaz/yconfig.h>
26 #include <yaz/log.h>
27 #include <yaz/comstack.h>
28 #include <yaz/xmalloc.h>
29 #include <yaz/statserv.h>
30
31 #include "eventl.h"
32
33
34 IOCHAN iochan_create(int fd,  struct sockaddr_in *addr_in, 
35                      IOC_CALLBACK cb, int flags)
36 {
37     IOCHAN new_iochan;
38
39     if (!(new_iochan = (IOCHAN)xmalloc(sizeof(*new_iochan))))
40         return 0;
41     new_iochan->destroyed = 0;
42     new_iochan->fd = fd;
43
44     if(addr_in){
45         new_iochan->addr_in.sin_family = addr_in->sin_family;
46         new_iochan->addr_in.sin_port = addr_in->sin_port;
47         new_iochan->addr_in.sin_addr = addr_in->sin_addr;
48         strncpy(new_iochan->addr_str, inet_ntoa(addr_in->sin_addr), 64);
49     }
50
51     new_iochan->flags = flags;
52     new_iochan->fun = cb;
53     new_iochan->force_event = 0;
54     new_iochan->last_event = new_iochan->max_idle = 0;
55     new_iochan->next = NULL;
56     return new_iochan;
57 }
58
59 int event_loop(IOCHAN *iochans)
60 {
61     do /* loop as long as there are active associations to process */
62     {
63         IOCHAN p, nextp;
64         fd_set in, out, except;
65         int res, max;
66         static struct timeval nullto = {0, 0}, to;
67         struct timeval *timeout;
68
69         FD_ZERO(&in);
70         FD_ZERO(&out);
71         FD_ZERO(&except);
72         timeout = &to; /* hang on select */
73         to.tv_sec = 30;
74         to.tv_usec = 0;
75         max = 0;
76         for (p = *iochans; p; p = p->next)
77         {
78             if (p->fd < 0)
79                 continue;
80             if (p->force_event)
81                 timeout = &nullto;        /* polling select */
82             if (p->flags & EVENT_INPUT)
83                 FD_SET(p->fd, &in);
84             if (p->flags & EVENT_OUTPUT)
85                 FD_SET(p->fd, &out);
86             if (p->flags & EVENT_EXCEPT)
87                 FD_SET(p->fd, &except);
88             if (p->fd > max)
89                 max = p->fd;
90         }
91         if ((res = select(max + 1, &in, &out, &except, timeout)) < 0)
92         {
93             if (errno == EINTR)
94                 continue;
95             else
96                 abort();
97         }
98         for (p = *iochans; p; p = p->next)
99         {
100             int force_event = p->force_event;
101             time_t now = time(0);
102
103             p->force_event = 0;
104             if (!p->destroyed && ((p->max_idle && now - p->last_event >
105                 p->max_idle) || force_event == EVENT_TIMEOUT))
106             {
107                 p->last_event = now;
108                 (*p->fun)(p, EVENT_TIMEOUT);
109             }
110             if (p->fd < 0)
111                 continue;
112             if (!p->destroyed && (FD_ISSET(p->fd, &in) ||
113                 force_event == EVENT_INPUT))
114             {
115                 p->last_event = now;
116                 (*p->fun)(p, EVENT_INPUT);
117             }
118             if (!p->destroyed && (FD_ISSET(p->fd, &out) ||
119                 force_event == EVENT_OUTPUT))
120             {
121                 p->last_event = now;
122                 (*p->fun)(p, EVENT_OUTPUT);
123             }
124             if (!p->destroyed && (FD_ISSET(p->fd, &except) ||
125                 force_event == EVENT_EXCEPT))
126             {
127                 p->last_event = now;
128                 (*p->fun)(p, EVENT_EXCEPT);
129             }
130         }
131         for (p = *iochans; p; p = nextp)
132         {
133             nextp = p->next;
134
135             if (p->destroyed)
136             {
137                 IOCHAN tmp = p, pr;
138
139                 /* Now reset the pointers */
140                 if (p == *iochans)
141                     *iochans = p->next;
142                 else
143                 {
144                     for (pr = *iochans; pr; pr = pr->next)
145                         if (pr->next == p)
146                             break;
147                     assert(pr); /* grave error if it weren't there */
148                     pr->next = p->next;
149                 }
150                 if (nextp == p)
151                     nextp = p->next;
152                 xfree(tmp);
153             }
154         }
155     }
156     while (*iochans);
157     return 0;
158 }
159
160 /*
161  * Local variables:
162  * c-basic-offset: 4
163  * indent-tabs-mode: nil
164  * End:
165  * vim: shiftwidth=4 tabstop=8 expandtab
166  */