From: Adam Dickmeiss Date: Mon, 4 Jan 2010 12:58:42 +0000 (+0100) Subject: Working on epoll socket layer X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=commitdiff_plain;h=3cb026de413f8130490ada85f2bc0b460172e4ef Working on epoll socket layer --- diff --git a/include/yaz/sock_man.h b/include/yaz/sock_man.h new file mode 100644 index 0000000..75bc841 --- /dev/null +++ b/include/yaz/sock_man.h @@ -0,0 +1,66 @@ +/* This file is part of the YAZ toolkit. + * Copyright (C) 1995-2009 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. + */ + +/** + * \file + * \brief socket manager + */ +#ifndef YAZ_SOCK_MAN_H +#define YAZ_SOCK_MAN_H + +#include +#include + +YAZ_BEGIN_CDECL + +typedef struct yaz_sock_man_s *yaz_sock_man_t; +typedef struct yaz_sock_chan_s *yaz_sock_chan_t; + +YAZ_EXPORT +yaz_sock_man_t yaz_sock_man_new(void); + +YAZ_EXPORT +void yaz_sock_man_destroy(yaz_sock_man_t man); + +YAZ_EXPORT +yaz_sock_chan_t yaz_sock_chan_new(yaz_sock_man_t srv, int fd, void *data); + +YAZ_EXPORT +void yaz_sock_chan_destroy(yaz_sock_man_t srv, yaz_sock_chan_t p); + +YAZ_END_CDECL + +#endif +/* + * Local variables: + * c-basic-offset: 4 + * c-file-style: "Stroustrup" + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ + diff --git a/src/Makefile.am b/src/Makefile.am index 032da2e..0eefdf0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -102,7 +102,8 @@ libyaz_la_SOURCES=version.c options.c log.c \ record_conv.c retrieval.c elementset.c snprintf.c query-charset.c \ copy_types.c match_glob.c poll.c daemon.c \ iconv_encode_marc8.c iconv_encode_iso_8859_1.c iconv_encode_wchar.c \ - iconv_decode_marc8.c iconv_decode_iso5426.c iconv_decode_danmarc.c sc.c + iconv_decode_marc8.c iconv_decode_iso5426.c iconv_decode_danmarc.c sc.c \ + sock_man.c libyaz_la_LDFLAGS=-version-info $(YAZ_VERSION_INFO) diff --git a/src/nanohttp.c b/src/nanohttp.c new file mode 100644 index 0000000..3c0e945 --- /dev/null +++ b/src/nanohttp.c @@ -0,0 +1,175 @@ +/* This file is part of the YAZ toolkit. + * Copyright (C) 1995-2009 Index Data + * See the file LICENSE for details. + */ +/** + * \file + * \brief Small HTTP server + */ + +#include +#include +#include +#include +#include +#include + +typedef struct yaz_nano_srv_s *yaz_nano_srv_t; +typedef struct yaz_nano_pkg_s *yaz_nano_pkg_t; + +struct yaz_nano_pkg_s { + void *handle; + int listener_id; + ODR encode_odr; + Z_GDU *request_gdu; + Z_GDU *response_gdu; +}; + +struct yaz_nano_srv_s { + COMSTACK *cs_listeners; + size_t num_listeners; + NMEM nmem; + struct yaz_poll_fd *fds; +}; + +void yaz_nano_srv_destroy(yaz_nano_srv_t p) +{ + if (p) + { + size_t i; + for (i = 0; i < p->num_listeners; i++) + if (p->cs_listeners[i]) + cs_close(p->cs_listeners[i]); + nmem_destroy(p->nmem); + } +} + +yaz_nano_srv_t yaz_nano_srv_create(const char **listeners_str) +{ + NMEM nmem = nmem_create(); + yaz_nano_srv_t p = nmem_malloc(nmem, sizeof(*p)); + size_t i; + for (i = 0; listeners_str[i]; i++) + ; + p->nmem = nmem; + p->chan_list = 0; + p->free_list = 0; + p->num_listeners = i; + p->cs_listeners = + nmem_malloc(nmem, p->num_listeners * sizeof(*p->cs_listeners)); + for (i = 0; i < p->num_listeners; i++) + { + void *ap; + const char *where = listeners_str[i]; + COMSTACK l = cs_create_host(where, 2, &ap); + p->cs_listeners[i] = 0; /* not OK (yet) */ + if (!l) + { + yaz_log(YLOG_WARN|YLOG_ERRNO, "cs_create_host(%s) failed", where); + } + else + { + if (cs_bind(l, ap, CS_SERVER) < 0) + { + if (cs_errno(l) == CSYSERR) + yaz_log(YLOG_FATAL|YLOG_ERRNO, "Failed to bind to %s", where); + else + yaz_log(YLOG_FATAL, "Failed to bind to %s: %s", where, + cs_strerror(l)); + cs_close(l); + } + else + p->cs_listeners[i] = l; /* success */ + } + } + /* check if all are OK */ + for (i = 0; i < p->num_listeners; i++) + if (!p->cs_listeners[i]) + { + yaz_nano_srv_destroy(p); + return 0; + } + + for (i = 0; i < p->num_listeners; i++) + { + struct socket_chan *chan = + socket_chan_new(p, cs_fileno(p->cs_listeners[i]), + p->cs_listeners + i); + socket_chan_set_mask(chan, yaz_poll_read | yaz_poll_except); + } + return p; +} + +Z_GDU *yaz_nano_pkg_req(yaz_nano_pkg_t pkg) +{ + return pkg->request_gdu; +} + +Z_GDU *yaz_nano_pkg_response(yaz_nano_pkg_t pkg) +{ + return pkg->response_gdu; +} + +ODR yaz_nano_pkg_encode(yaz_nano_pkg_t pkg) +{ + return pkg->encode_odr; +} + +int yaz_nano_pkg_listener_id(yaz_nano_pkg_t pkg) +{ + return pkg->listener_id; +} + +yaz_nano_pkg_t yaz_nano_srv_get_pkg(yaz_nano_srv_t p) +{ + size_t i; + int ret; + int num_fds = 0; + struct yaz_poll_fd *fds; + struct socket_chan *chan = p->chan_list; + for (chan = p->chan_list; chan; chan = chan->next) + num_fds++; + fds = xmalloc(num_fds * sizeof(*fds)); + for (i = 0, chan = p->chan_list; chan; chan = chan->next) + { + fds[i].input_mask = chan->mask; + fds[i].fd = chan->fd; + fds[i].client_data = chan; + } + ret = yaz_poll(fds, num_fds, 0, 0); + if (ret == -1) + { + yaz_log(YLOG_WARN, "yaz_poll error"); + } + else if (ret == 0) + { + yaz_log(YLOG_LOG, "yaz_poll timeout"); + } + else + { + for (i = 0, chan = p->chan_list; chan; chan = chan->next) + { + if (fds[i].output_mask) + { + yaz_log(YLOG_LOG, "event on chan=%p", chan); + } + } + } + xfree(fds); + return 0; +} + +void yaz_nano_srv_put_pkg(yaz_nano_srv_t p, yaz_nano_pkg_t pkg) +{ + +} + +/* + * Local variables: + * c-basic-offset: 4 + * c-file-style: "Stroustrup" + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ + diff --git a/src/sock_man.c b/src/sock_man.c new file mode 100644 index 0000000..725a901 --- /dev/null +++ b/src/sock_man.c @@ -0,0 +1,122 @@ + +#include +#include +#include +#include + +struct yaz_sock_man_s { + yaz_sock_chan_t chan_list; + yaz_sock_chan_t free_list; + NMEM nmem; + int epoll_handle; + int maxevents; + yaz_sock_chan_t *events; +}; + +struct yaz_sock_chan_s { + yaz_sock_chan_t next; + yaz_sock_chan_t prev; + int fd; + unsigned mask; + void *data; +}; + +yaz_sock_man_t yaz_sock_man_new(void) +{ + NMEM nmem = nmem_create(); + yaz_sock_man_t man = nmem_malloc(nmem, sizeof(*man)); + man->nmem = nmem; + man->chan_list = 0; + man->free_list = 0; + man->epoll_handle = epoll_create(100); + man->maxevents = 30; + man->events = nmem_malloc(nmem, man->maxevents * sizeof(*man->events)); + if (man->epoll_handle == -1) + { + yaz_sock_man_destroy(man); + return 0; + } + return man; +} + +void yaz_sock_man_destroy(yaz_sock_man_t man) +{ + if (man) + { + if (man->epoll_handle != -1) + close(man->epoll_handle); + assert(man->chan_list == 0); + nmem_destroy(man->nmem); + } +} + +yaz_sock_chan_t yaz_sock_chan_new(yaz_sock_man_t srv, int fd, void *data) +{ + yaz_sock_chan_t p; + if (srv->free_list) + { + p = srv->free_list; + srv->free_list = p->next; + } + else + p = nmem_malloc(srv->nmem, sizeof(*p)); + p->next = srv->chan_list; + if (p->next) + p->next->prev = p; + p->prev = 0; + srv->chan_list = p; + + p->fd = fd; + p->mask = 0; + p->data = data; + return p; +} + +void yaz_sock_chan_destroy(yaz_sock_man_t srv, yaz_sock_chan_t p) +{ + if (p->prev) + p->prev->next = p->next; + else + { + assert(srv->chan_list == p); + srv->chan_list = p->next; + } + + if (p->next) + p->next->prev = p->prev; + + p->next = srv->free_list; + p->prev = 0; + srv->free_list = p; +} + +yaz_sock_chan_t yaz_sock_man_wait(yaz_sock_man_t man) +{ + return 0; +} + +void yaz_sock_chan_set_mask(yaz_sock_chan_t chan, unsigned mask) +{ + chan->mask = mask; +} + +unsigned yaz_sock_get_mask(yaz_sock_chan_t chan) +{ + return chan->mask; +} + +void *yaz_sock_chan_get_data(yaz_sock_chan_t chan) +{ + return chan->data; +} + + +/* + * Local variables: + * c-basic-offset: 4 + * c-file-style: "Stroustrup" + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ +