From 8b4a08403ae705e22b604bffa4577ac403b7de8d Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Fri, 9 Nov 2007 16:46:43 +0000 Subject: [PATCH] Implemented yaz_poll - select/poll wrapper. --- include/yaz/Makefile.am | 4 +- include/yaz/poll.h | 85 +++++++++++++++++++++ src/Makefile.am | 4 +- src/poll.c | 176 ++++++++++++++++++++++++++++++++++++++++++ src/zoom-socket.c | 194 +++++++++-------------------------------------- win/makefile | 5 +- 6 files changed, 303 insertions(+), 165 deletions(-) create mode 100644 include/yaz/poll.h create mode 100644 src/poll.c diff --git a/include/yaz/Makefile.am b/include/yaz/Makefile.am index 24f498e..76a8e0a 100644 --- a/include/yaz/Makefile.am +++ b/include/yaz/Makefile.am @@ -1,4 +1,4 @@ -## $Id: Makefile.am,v 1.49 2007-11-08 09:29:38 adam Exp $ +## $Id: Makefile.am,v 1.50 2007-11-09 16:46:43 adam Exp $ noinst_HEADERS = icu_I18N.h @@ -11,7 +11,7 @@ pkginclude_HEADERS= backend.h ccl.h ccl_xml.h cql.h comstack.h \ yaz-ccl.h yaz-iconv.h yaz-util.h yaz-version.h yconfig.h proto.h \ xmlquery.h libxml2_error.h xmltypes.h snprintf.h query-charset.h \ mutex.h oid_db.h oid_util.h oid_std.h tokenizer.h copy_types.h \ - icu.h match_glob.h \ + icu.h match_glob.h poll.h \ \ ill.h ill-core.h item-req.h oclc-ill-req-ext.h z-accdes1.h z-accform1.h \ z-acckrb1.h z-core.h z-date.h z-diag1.h z-espec1.h z-estask.h z-exp.h \ diff --git a/include/yaz/poll.h b/include/yaz/poll.h new file mode 100644 index 0000000..7edc317 --- /dev/null +++ b/include/yaz/poll.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 1995-2007, Index Data + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Index Data nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* $Id: poll.h,v 1.1 2007-11-09 16:46:43 adam Exp $ */ + +/** + * \file + * \brief Poll , select wrappers + */ +#ifndef YAZ_POLL_H +#define YAZ_POLL_H + +#include +#include + +YAZ_BEGIN_CDECL + +/** \brief select/poll masks .. timeout is "output" only */ +enum yaz_poll_mask { + yaz_poll_read = 1, + yaz_poll_write = 2, + yaz_poll_except = 4, + yaz_poll_timeout = 8, +}; + +/** \brief select/poll fd info */ +struct yaz_poll_fd { + /** input mask passed to select/poll */ + enum yaz_poll_mask input_mask; + /** resulting mask as returned by select/poll */ + enum yaz_poll_mask output_mask; + /** file descriptor to use */ + int fd; + /** user-defined data */ + void *client_data; +}; + +/** \brief socket poll wrapper using select + */ +int yaz_poll_select(struct yaz_poll_fd *fds, int num_fds, int timeout); + +/** \brief socket poll using poll */ +int yaz_poll_poll(struct yaz_poll_fd *fds, int num_fds, int timeout); + +/** \brief poll wrapper for poll or select + + This functions calls yaz_poll_poll on systems where poll is + available and yaz_poll_select where it it unavailable. +*/ +int yaz_poll(struct yaz_poll_fd *fds, int num_fds, int timeout); + +YAZ_END_CDECL + +#endif +/* + * Local variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ + diff --git a/src/Makefile.am b/src/Makefile.am index 1025a62..524b192 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,6 @@ ## This file is part of the YAZ toolkit. ## Copyright (C) 1995-2007, Index Data, All rights reserved. -## $Id: Makefile.am,v 1.70 2007-10-24 13:50:02 adam Exp $ +## $Id: Makefile.am,v 1.71 2007-11-09 16:46:43 adam Exp $ YAZ_VERSION_INFO=3:0:0 @@ -94,7 +94,7 @@ libyaz_la_SOURCES=version.c options.c log.c \ xmlquery.c http.c \ mime.c mime.h oid_util.c tokenizer.c \ record_conv.c retrieval.c elementset.c snprintf.c query-charset.c \ - copy_types.c match_glob.c + copy_types.c match_glob.c poll.c libyaz_la_LDFLAGS=-version-info $(YAZ_VERSION_INFO) diff --git a/src/poll.c b/src/poll.c new file mode 100644 index 0000000..c877f0a --- /dev/null +++ b/src/poll.c @@ -0,0 +1,176 @@ +/* + * Copyright (C) 1995-2007, Index Data ApS + * See the file LICENSE for details. + * + * $Id: poll.c,v 1.1 2007-11-09 16:46:43 adam Exp $ + */ +/** + * \file + * \brief Select, poll wrapper + */ + +#include +#include +#include + +#include +#include +#include + +#if HAVE_SYS_TYPES_H +#include +#endif +#if HAVE_SYS_TIME_H +#include +#endif +#if HAVE_SYS_POLL_H +#include +#endif +#if HAVE_SYS_SELECT_H +#include +#endif +#ifdef WIN32 +#if FD_SETSIZE < 512 +#define FD_SETSIZE 512 +#endif +#include +#endif + +/* + Note that yaz_poll_select is limited as to how many file + descriptors it can multiplex due to its use of select() which in + turn uses the statically defined fd_set type to be a bitmap of the + file descriptors to check. On Ubuntu 6.06 (and almost certainly on + Debian, and probably on all Linuxes, and maybe all Unixes) this is + by default set to 1024 (though it may be possible to override this + using a #define before including -- I've not tried + this). 1024 file descriptors is a lot, but not enough in all + cases, e.g. when running IRSpy on a large target database. So you + should ensure that YAZ uses ZOOM_yaz_poll_poll() when possible. +*/ +int yaz_poll_select(struct yaz_poll_fd *fds, int num_fds, int timeout) +{ + struct timeval tv; + fd_set input, output, except; + int i, r; + int max_fd = 0; + + FD_ZERO(&input); + FD_ZERO(&output); + FD_ZERO(&except); + + assert(num_fds > 0); + for (i = 0; i < num_fds; i++) + { + enum yaz_poll_mask mask = fds[i].input_mask; + int fd = fds[i].fd; + + if (mask & yaz_poll_read) + FD_SET(fd, &input); + if (mask & yaz_poll_write) + FD_SET(fd, &output); + if (mask & yaz_poll_except) + FD_SET(fd, &except); + if (max_fd < fd) + max_fd = fd; + } + tv.tv_sec = timeout; + tv.tv_usec = 0; + + while ((r = select(max_fd+1, &input, &output, &except, + (timeout == -1 ? 0 : &tv))) < 0 && errno == EINTR) + { + ; + } + for (i = 0; i < num_fds; i++) + { + enum yaz_poll_mask mask = 0; + int fd = fds[i].fd; + if (!r) + mask += yaz_poll_timeout; + else + { + if (FD_ISSET(fd, &input)) + mask += yaz_poll_read; + if (FD_ISSET(fd, &output)) + mask += yaz_poll_write; + if (FD_ISSET(fd, &except)) + mask += yaz_poll_except; + } + fds[i].output_mask = mask; + } + return r; +} + +#if HAVE_SYS_POLL_H +int yaz_poll_poll(struct yaz_poll_fd *fds, int num_fds, int timeout) +{ + int r; + struct pollfd *pollfds = (struct pollfd *) + xmalloc(num_fds * sizeof *pollfds); + int i; + + assert(num_fds > 0); + for (i = 0; i < num_fds; i++) + { + enum yaz_poll_mask mask = fds[i].input_mask; + int fd = fds[i].fd; + short poll_events = 0; + + if (mask & yaz_poll_read) + poll_events += POLLIN; + if (mask & yaz_poll_write) + poll_events += POLLOUT; + if (mask & yaz_poll_except) + poll_events += POLLERR; + pollfds[i].fd = fd; + pollfds[i].events = poll_events; + pollfds[i].revents = 0; + } + while ((r = poll(pollfds, num_fds, + (timeout == -1 ? -1 : timeout * 1000))) < 0 + && errno == EINTR) + { + ; + } + if (r >= 0) + { + for (i = 0; i < num_fds; i++) + { + enum yaz_poll_mask mask = 0; + if (!r) + mask += yaz_poll_timeout; + else + { + if (pollfds[i].revents & POLLIN) + mask += yaz_poll_read; + if (pollfds[i].revents & POLLOUT) + mask += yaz_poll_write; + if (pollfds[i].revents & POLLERR) + mask += yaz_poll_except; + } + fds[i].output_mask = mask; + } + } + xfree(pollfds); + return r; +} +#endif + +int yaz_poll(struct yaz_poll_fd *fds, int num_fds, int timeout) +{ +#if YAZ_HAVE_SYS_POLL_H + return yaz_poll_poll(fds, num_fds, timeout); +#else + return yaz_poll_select(fds, num_fds, timeout); +#endif +} + +/* + * Local variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ + diff --git a/src/zoom-socket.c b/src/zoom-socket.c index 5950baa..da72eda 100644 --- a/src/zoom-socket.c +++ b/src/zoom-socket.c @@ -2,7 +2,7 @@ * Copyright (C) 1995-2007, Index Data ApS * See the file LICENSE for details. * - * $Id: zoom-socket.c,v 1.4 2007-05-06 20:12:20 adam Exp $ + * $Id: zoom-socket.c,v 1.5 2007-11-09 16:46:43 adam Exp $ */ /** * \file zoom-socket.c @@ -23,127 +23,18 @@ #if HAVE_SYS_TIME_H #include #endif -#if HAVE_SYS_POLL_H -#include -#endif -#if HAVE_SYS_SELECT_H -#include -#endif -#ifdef WIN32 -#if FD_SETSIZE < 512 -#define FD_SETSIZE 512 -#endif -#include -#endif +#include -/* - * Note that ZOOM_event_sys_select() is limited as to how many file - * descriptors it can multiplex due to its use of select() which in - * turn uses the statically defined fd_set type to be a bitmap of the - * file descriptors to check. On Ubuntu 6.06 (and almost certainly on - * Debian, and probably on all Linuxes, and maybe all Unixes) this is - * by default set to 1024 (though it may be possible to override this - * using a #define before including -- I've not tried - * this). 1024 file descriptors is a lot, but not enough in all - * cases, e.g. when running IRSpy on a large target database. So you - * should ensure that YAZ uses ZOOM_event_sys_poll() when possible. - */ ZOOM_API(int) - ZOOM_event_sys_select(int no, ZOOM_connection *cs) + ZOOM_event_sys_yaz_poll(int no, ZOOM_connection *cs) { - struct timeval tv; - fd_set input, output, except; - int i, r; - int max_fd = 0; - int timeout = 30; - int nfds = 0; - - FD_ZERO(&input); - FD_ZERO(&output); - FD_ZERO(&except); - - for (i = 0; i= 0) { - ZOOM_connection c = poll_cs[i]; - if (r) + for (i = 0; i < nfds; i++) { - int mask = 0; - if (pollfds[i].revents & POLLIN) - mask += ZOOM_SELECT_READ; - if (pollfds[i].revents & POLLOUT) - mask += ZOOM_SELECT_WRITE; - if (pollfds[i].revents & POLLERR) - mask += ZOOM_SELECT_EXCEPT; - ZOOM_connection_fire_event_socket(c, mask); + ZOOM_connection c = yp[i].client_data; + enum yaz_poll_mask output_mask = yp[i].output_mask; + if (output_mask & yaz_poll_timeout) + ZOOM_connection_fire_event_timeout(c); + else + { + int mask = 0; + if (output_mask & yaz_poll_read) + mask += ZOOM_SELECT_READ; + if (output_mask & yaz_poll_write) + mask += ZOOM_SELECT_WRITE; + if (output_mask & yaz_poll_except) + mask += ZOOM_SELECT_EXCEPT; + ZOOM_connection_fire_event_socket(c, mask); + } } - else - ZOOM_connection_fire_event_timeout(c); } - xfree(pollfds); - xfree(poll_cs); + xfree(yp); return r; } -#endif ZOOM_API(int) ZOOM_event(int no, ZOOM_connection *cs) @@ -222,11 +102,7 @@ ZOOM_API(int) r = ZOOM_event_nonblock(no, cs); if (r) return r; -#if HAVE_SYS_POLL_H - ZOOM_event_sys_poll(no, cs); -#else - ZOOM_event_sys_select(no, cs); -#endif + ZOOM_event_sys_yaz_poll(no, cs); return ZOOM_event_nonblock(no, cs); } diff --git a/win/makefile b/win/makefile index 7c78c14..727a593 100644 --- a/win/makefile +++ b/win/makefile @@ -1,6 +1,6 @@ # Copyright (C) 1995-2007, Index Data ApS # All rights reserved. -# $Id: makefile,v 1.137 2007-10-24 13:50:04 adam Exp $ +# $Id: makefile,v 1.138 2007-11-09 16:46:43 adam Exp $ # # Programmed by # Heikki Levanto & Adam Dickmeiss @@ -439,7 +439,8 @@ MISC_OBJS= \ $(OBJDIR)\tokenizer.obj \ $(OBJDIR)\copy_types.obj \ $(OBJDIR)\http.obj \ - $(OBJDIR)\match_glob.obj + $(OBJDIR)\match_glob.obj \ + $(OBJDIR)\poll.obj Z3950_OBJS= \ $(OBJDIR)\z-date.obj\ -- 1.7.10.4