47 #include <yaz/yconfig.h>
49 #include <yaz/comstack.h>
50 #include <yaz/xmalloc.h>
51 #include <yaz/mutex.h>
54 #include <sys/resource.h>
75 yaz_log(YLOG_DEBUG,
"%s iochans=%d",
76 delta == 0 ?
"" : (delta > 0 ?
"INC" :
"DEC"), iochans);
97 #define iochans_count(x) 0
98 #define iochans_count_total(x) 0
120 man->
log_level = yaz_log_module_level(
"iochan");
127 struct rlimit limit_data;
128 getrlimit(RLIMIT_NOFILE, &limit_data);
129 yaz_log(YLOG_LOG,
"getrlimit NOFILE cur=%ld max=%ld",
130 (
long) limit_data.rlim_cur, (
long) limit_data.rlim_max);
131 man->
limit_fd = limit_data.rlim_cur - 200;
136 yaz_log(YLOG_LOG,
"iochan threads %d limit fd %d", no_threads,
157 if ((*mp)->sel_thread)
160 yaz_mutex_enter((*mp)->iochan_mutex);
161 c = (*mp)->channel_list;
162 (*mp)->channel_list = NULL;
163 yaz_mutex_leave((*mp)->iochan_mutex);
166 yaz_mutex_destroy(&(*mp)->iochan_mutex);
175 int r = 0, no_fds = 0;
178 yaz_log(man->
log_level,
"iochan_add : chan=%p channel list=%p", chan,
189 yaz_log(YLOG_WARN,
"max channels %d in use", no_fds);
213 if (!(new_iochan = (
IOCHAN) xmalloc(
sizeof(*new_iochan))))
218 new_iochan->
flags = flags;
219 new_iochan->
fun = cb;
221 new_iochan->
next = NULL;
232 yaz_log(p->
man->
log_level,
"eventl: work begin chan=%p name=%s event=%d",
244 yaz_log(p->
man->
log_level,
"eventl: work end chan=%p name=%s event=%d", p,
253 "eventl: work add chan=%p name=%s event=%d", p,
270 struct yaz_poll_fd *fds;
272 int connection_fired = 0;
279 for (p = start; p; p = p->
next)
293 fds[i].input_mask = yaz_poll_read;
294 fds[i].client_data = 0;
297 for (p = start; p; p = p->
next, i++)
300 fds[i].client_data = p;
302 fds[i].input_mask = 0;
310 fds[i].input_mask |= yaz_poll_read;
312 fds[i].input_mask |= yaz_poll_write;
314 fds[i].input_mask |= yaz_poll_except;
315 if (fds[i].input_mask)
319 yaz_log(man->
log_level,
"yaz_poll begin tv_sec=%d nofds=%d", tv_sec,
321 res = yaz_poll(fds, no_fds, tv_sec, 0);
322 yaz_log(man->
log_level,
"yaz_poll returned res=%d", res);
329 yaz_log(YLOG_ERRNO | YLOG_WARN,
"poll");
336 assert(fds[i].fd == man->
sel_fd);
337 if (fds[i].output_mask)
341 yaz_log(man->
log_level,
"eventl: sel input on sel_fd=%d",
346 "eventl: got thread result chan=%p name=%s", chan,
355 for (p = start; p; p = p->
next)
357 yaz_log(man->
log_level,
"%d channels", no);
359 for (p = start; p; p = p->
next)
361 time_t now = time(0);
367 "eventl: skip destroyed chan=%p name=%s", p,
374 "eventl: skip chan=%p name=%s users=%d", p,
384 if (fds[i].fd >= 0 && p->
fd == fds[i].fd)
386 if (fds[i].output_mask & yaz_poll_read)
391 if (fds[i].output_mask & yaz_poll_write)
396 if (fds[i].output_mask & yaz_poll_except)
406 !strcmp(p->
name,
"connection_socket"))
409 if (connection_fired == 0)
418 assert(inv_start == start);
420 for (nextp = iochans; *nextp; )
439 yaz_log(man->
log_level,
"iochan_man_events. Using %d threads",
void iochan_man_events(iochan_man_t man)
void iochan_man_destroy(iochan_man_t *mp)
IOCHAN iochan_create(int fd, IOC_CALLBACK cb, int flags, const char *name)
static void run_fun(iochan_man_t man, IOCHAN p)
iochan_man_t iochan_man_create(int no_threads, int max_sockets)
static void work_handler(void *work_data)
static int event_loop(iochan_man_t man, IOCHAN *iochans)
static int iochan_use(int delta)
void iochan_destroy(IOCHAN chan)
int iochans_count_total(void)
static int no_iochans_total
int iochan_add(iochan_man_t man, IOCHAN chan, int slack)
IOCHAN iochan_destroy_real(IOCHAN chan)
void(* IOC_CALLBACK)(struct iochan *i, int event)
void * sel_thread_result(sel_thread_t p)
gets result of work
void sel_thread_add(sel_thread_t p, void *data)
adds work to be carried out in thread
sel_thread_t sel_thread_create(void(*work_handler)(void *work_data), void(*work_destroy)(void *work_data), int *read_fd, int no_of_threads)
creates select thread
void sel_thread_destroy(sel_thread_t p)
destorys select thread