From cc9efe948e97e8f6f785bdd2e37a17ba0cce672d Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Thu, 15 Oct 2015 11:44:01 +0200 Subject: [PATCH] First work on usage limit --- configure.ac | 4 ++-- src/connection.c | 17 +++++++++++++---- src/eventl.c | 31 +++++++++++++++++++++++++++---- src/eventl.h | 2 +- 4 files changed, 43 insertions(+), 11 deletions(-) diff --git a/configure.ac b/configure.ac index 85ef2db..be9d6b1 100644 --- a/configure.ac +++ b/configure.ac @@ -11,7 +11,7 @@ m4_esyscmd([. ./IDMETA; echo $VERSION|tr -d '\n']), AC_CONFIG_HEADERS(src/config.h) -AC_CONFIG_SRCDIR([configure.ac]) +AC_CONFIG_SRCDIR([configure.ac]) AC_CONFIG_AUX_DIR([config]) AC_CANONICAL_SYSTEM @@ -48,7 +48,7 @@ if test "$checkBoth" = "1"; then AC_CHECK_FUNC([accept], , [LIBS=$oldLibs]) fi AC_CHECK_FUNC([gethostbyname], ,[AC_CHECK_LIB(nsl, main, [LIBS="$LIBS -lnsl"])]) -AC_CHECK_FUNCS([getaddrinfo mallinfo]) +AC_CHECK_FUNCS([getaddrinfo mallinfo getrlimit]) if test -d ${srcdir}/.git; then sha=`git show --pretty=format:%H|head -1` diff --git a/src/connection.c b/src/connection.c index 98a73e0..c2c4bea 100644 --- a/src/connection.c +++ b/src/connection.c @@ -333,6 +333,7 @@ static int connection_connect(struct connection *con, iochan_man_t iochan_man) const char *sru; const char *sru_version = 0; const char *value; + int r = 0; WRBUF w; struct session_database *sdb = client_get_database(con->client); @@ -423,12 +424,20 @@ static int connection_connect(struct connection *con, iochan_man_t iochan_man) con->state = Conn_Connecting; iochan_settimeout(con->iochan, con->operation_timeout); iochan_setdata(con->iochan, con); - iochan_add(iochan_man, con->iochan); - - client_set_state(con->client, Client_Connecting); + if (iochan_add(iochan_man, con->iochan)) + { + yaz_log(YLOG_FATAL, "Out of connections"); + ZOOM_connection_destroy(con->link); + con->link = 0; + r = -1; + } + else + { + client_set_state(con->client, Client_Connecting); + } ZOOM_options_destroy(zoptions); wrbuf_destroy(w); - return 0; + return r; } // Ensure that client has a connection associated diff --git a/src/eventl.c b/src/eventl.c index 40dfeb4..da2f7f9 100644 --- a/src/eventl.c +++ b/src/eventl.c @@ -50,6 +50,7 @@ #include #include #include +#include #include "eventl.h" #include "sel_thread.h" @@ -103,6 +104,7 @@ struct iochan_man_s { int log_level; YAZ_MUTEX iochan_mutex; int size_fds; + int limit_fd; struct yaz_poll_fd *fds; }; @@ -117,6 +119,16 @@ iochan_man_t iochan_man_create(int no_threads) man->iochan_mutex = 0; man->size_fds = 0; man->fds = 0; + man->limit_fd = 0; +#if HAVE_GETRLIMIT + { + struct rlimit limit_data; + getrlimit(RLIMIT_NOFILE, &limit_data); + yaz_log(YLOG_LOG, "getrlimit NOFILE cur=%ld max=%ld", + (long) limit_data.rlim_cur, (long) limit_data.rlim_max); + man->limit_fd = limit_data.rlim_cur - 200; + } +#endif yaz_mutex_create(&man->iochan_mutex); return man; } @@ -152,15 +164,26 @@ void iochan_man_destroy(iochan_man_t *mp) } } -void iochan_add(iochan_man_t man, IOCHAN chan) +int iochan_add(iochan_man_t man, IOCHAN chan) { + int r = 0, no_fds = 0; + IOCHAN p; chan->man = man; - yaz_mutex_enter(man->iochan_mutex); + yaz_log(man->log_level, "iochan_add : chan=%p channel list=%p", chan, man->channel_list); - chan->next = man->channel_list; - man->channel_list = chan; + yaz_mutex_enter(man->iochan_mutex); + for (p = man->channel_list; p; p = p->next) + no_fds++; + if (man->limit_fd > 0 && no_fds >= man->limit_fd) + r = -1; + else + { + chan->next = man->channel_list; + man->channel_list = chan; + } yaz_mutex_leave(man->iochan_mutex); + return r; } IOCHAN iochan_create(int fd, IOC_CALLBACK cb, int flags, const char *name) diff --git a/src/eventl.h b/src/eventl.h index 92f9a53..392b000 100644 --- a/src/eventl.h +++ b/src/eventl.h @@ -52,7 +52,7 @@ typedef struct iochan iochan_man_t iochan_man_create(int no_threads); -void iochan_add(iochan_man_t man, IOCHAN chan); +int iochan_add(iochan_man_t man, IOCHAN chan); void iochan_man_events(iochan_man_t man); void iochan_man_destroy(iochan_man_t *mp); -- 1.7.10.4