YAZ 5.35.1
eventl.c
Go to the documentation of this file.
1/* This file is part of the YAZ toolkit.
2 * Copyright (C) Index Data
3 * See the file LICENSE for details.
4 */
12#if HAVE_CONFIG_H
13#include <config.h>
14#endif
15
16#include <assert.h>
17#include <errno.h>
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21
22#if HAVE_SYS_TYPES_H
23#include <sys/types.h>
24#endif
25#if HAVE_SYS_TIME_H
26#include <sys/time.h>
27#endif
28
29#include <yaz/poll.h>
30
31#include <yaz/log.h>
32#include <yaz/comstack.h>
33#include <yaz/xmalloc.h>
34#include <yaz/errno.h>
35#include "eventl.h"
36#include "session.h"
37#include <yaz/statserv.h>
38
39static int log_level=0;
41
42IOCHAN iochan_create(int fd, IOC_CALLBACK cb, int flags, int chan_id)
43{
44 IOCHAN new_iochan;
45
47 {
50 }
51
52 if (!(new_iochan = (IOCHAN)xmalloc(sizeof(*new_iochan))))
53 return 0;
54 new_iochan->destroyed = 0;
55 new_iochan->fd = fd;
56 new_iochan->flags = flags;
57 new_iochan->fun = cb;
58 new_iochan->force_event = 0;
59 new_iochan->last_event = new_iochan->max_idle = 0;
60 new_iochan->next = NULL;
61 new_iochan->chan_id = chan_id;
62 return new_iochan;
63}
64
65
67{
68 struct yaz_poll_fd fds;
69 int res;
70
71 fds.fd = chan->fd;
73 res = yaz_poll(&fds, 1, 0, 0);
74 if (res == 0)
75 return 1;
76 if (!ir_read(chan, EVENT_INPUT))
77 return 0;
78 return 1;
79}
80
81int iochan_event_loop(IOCHAN *iochans, int *watch_sig)
82{
83 do /* loop as long as there are active associations to process */
84 {
85 IOCHAN p, nextp;
86 int i;
87 int tv_sec = 3600;
88 int no_fds = 0;
89 struct yaz_poll_fd *fds = 0;
90 int res;
91 time_t now = time(0);
92
93 for (p = *iochans; p; p = p->next)
94 no_fds++;
95 fds = (struct yaz_poll_fd *) xmalloc(no_fds * sizeof(*fds));
96 for (i = 0, p = *iochans; p; p = p->next, i++)
97 {
98 time_t w, ftime;
100 yaz_log(log_level, "fd=%d flags=%d force_event=%d",
101 p->fd, p->flags, p->force_event);
102 if (p->force_event)
103 tv_sec = 0; /* polling select */
104 if (p->flags & EVENT_INPUT)
106 if (p->flags & EVENT_OUTPUT)
108 if (p->flags & EVENT_EXCEPT)
110 if (p->max_idle && p->last_event)
111 {
112 ftime = p->last_event + p->max_idle;
113 if (ftime < now)
114 w = p->max_idle;
115 else
116 w = ftime - now;
117 /* tv_sec will be minimum wait.. */
118 if (w < tv_sec)
119 tv_sec = (int) w; /* can hold it because w < tv_sec */
120 }
121 fds[i].fd = p->fd;
122 fds[i].input_mask = input_mask;
123 }
124 res = yaz_poll(fds, no_fds, tv_sec, 0);
125 if (res < 0)
126 {
127 if (yaz_errno() == EINTR)
128 {
129 xfree(fds);
130 if (watch_sig && *watch_sig)
131 break;
132 continue;
133 }
134 else
135 {
136 yaz_log(YLOG_WARN|YLOG_ERRNO, "yaz_poll");
137 xfree(fds);
138 continue;
139 }
140 }
141 now = time(0);
142 for (i = 0, p = *iochans; p; p = p->next, i++)
143 {
144 int force_event = p->force_event;
146
147 p->force_event = 0;
148 if (!p->destroyed && ((output_mask & yaz_poll_read) ||
149 force_event == EVENT_INPUT))
150 {
151 p->last_event = now;
152 (*p->fun)(p, EVENT_INPUT);
153 }
154 if (!p->destroyed && ((output_mask & yaz_poll_write) ||
155 force_event == EVENT_OUTPUT))
156 {
157 p->last_event = now;
158 (*p->fun)(p, EVENT_OUTPUT);
159 }
160 if (!p->destroyed && ((output_mask & yaz_poll_except) ||
161 force_event == EVENT_EXCEPT))
162 {
163 p->last_event = now;
164 (*p->fun)(p, EVENT_EXCEPT);
165 }
166 if (!p->destroyed && ((p->max_idle && now - p->last_event >=
167 p->max_idle) || force_event == EVENT_TIMEOUT))
168 {
169 p->last_event = now;
170 (*p->fun)(p, EVENT_TIMEOUT);
171 }
172 }
173 xfree(fds);
174 for (p = *iochans; p; p = nextp)
175 {
176 nextp = p->next;
177
178 if (p->destroyed)
179 {
180 IOCHAN tmp = p, pr;
181
182 /* We need to inform the threadlist that this channel has been destroyed */
184
185 /* Now reset the pointers */
186 if (p == *iochans)
187 *iochans = p->next;
188 else
189 {
190 for (pr = *iochans; pr; pr = pr->next)
191 if (pr->next == p)
192 break;
193 assert(pr); /* grave error if it weren't there */
194 pr->next = p->next;
195 }
196 if (nextp == p)
197 nextp = p->next;
198 xfree(tmp);
199 }
200 }
201 }
202 while (*iochans);
203 return 0;
204}
205/*
206 * Local variables:
207 * c-basic-offset: 4
208 * c-file-style: "Stroustrup"
209 * indent-tabs-mode: nil
210 * End:
211 * vim: shiftwidth=4 tabstop=8 expandtab
212 */
213
Header for COMSTACK.
int yaz_errno(void)
returns errno
Definition errno.c:31
Header for errno utilities.
int iochan_event_loop(IOCHAN *iochans, int *watch_sig)
Definition eventl.c:81
IOCHAN iochan_create(int fd, IOC_CALLBACK cb, int flags, int chan_id)
Definition eventl.c:42
int iochan_is_alive(IOCHAN chan)
Definition eventl.c:66
static int log_level
Definition eventl.c:39
static int log_level_initialized
Definition eventl.c:40
Definitions for event loop handling for GFS.
#define EVENT_TIMEOUT
Definition eventl.h:52
#define EVENT_INPUT
Definition eventl.h:49
#define EVENT_OUTPUT
Definition eventl.h:50
void statserv_remove(IOCHAN pIOChannel)
Definition statserv.c:928
void(* IOC_CALLBACK)(struct iochan *i, int event)
Definition eventl.h:43
#define EVENT_EXCEPT
Definition eventl.h:51
void yaz_log(int level, const char *fmt,...)
Writes log message.
Definition log.c:487
int yaz_log_module_level(const char *name)
returns level for module
Definition log.c:586
Logging utility.
#define YLOG_WARN
log level: warning
Definition log.h:46
#define YLOG_ERRNO
log level: append system error message
Definition log.h:50
int yaz_poll(struct yaz_poll_fd *fds, int num_fds, int sec, int nsec)
poll wrapper for poll or select
Definition poll.c:161
Poll, select wrappers.
#define yaz_poll_add(var, value)
Definition poll.h:76
yaz_poll_mask
select/poll masks .. timeout is "output" only
Definition poll.h:41
@ yaz_poll_read
Definition poll.h:43
@ yaz_poll_except
Definition poll.h:45
@ yaz_poll_none
Definition poll.h:42
@ yaz_poll_write
Definition poll.h:44
int ir_read(IOCHAN h, int event)
Definition seshigh.c:266
Internal header for GFS.
Header for GFS (Obsolete. Use yaz/backend.h)
int fd
Definition eventl.h:47
time_t max_idle
Definition eventl.h:58
struct iochan * next
Definition eventl.h:60
int chan_id
Definition eventl.h:61
time_t last_event
Definition eventl.h:57
int force_event
Definition eventl.h:53
int destroyed
Definition eventl.h:56
int flags
Definition eventl.h:48
IOC_CALLBACK fun
Definition eventl.h:54
select/poll fd info
Definition poll.h:50
enum yaz_poll_mask output_mask
Definition poll.h:54
enum yaz_poll_mask input_mask
Definition poll.h:52
int fd
Definition poll.h:56
Header for memory handling functions.
#define xfree(x)
utility macro which calls xfree_f
Definition xmalloc.h:53
#define xmalloc(x)
utility macro which calls malloc_f
Definition xmalloc.h:49