AC_CONFIG_HEADERS(src/config.h)
-AC_CONFIG_SRCDIR([configure.ac])
+AC_CONFIG_SRCDIR([configure.ac])
AC_CONFIG_AUX_DIR([config])
AC_CANONICAL_SYSTEM
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`
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);
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
#include <yaz/xmalloc.h>
#include <yaz/mutex.h>
#include <yaz/poll.h>
+#include <sys/resource.h>
#include "eventl.h"
#include "sel_thread.h"
int log_level;
YAZ_MUTEX iochan_mutex;
int size_fds;
+ int limit_fd;
struct yaz_poll_fd *fds;
};
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;
}
}
}
-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)
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);