in main thread).
</para>
</refsect2>
+ <refsect2 id="config-sockets">
+ <title>sockets</title>
+ <para>
+ This section is optional and is supported for Pazpar2 version 1.13.0 and
+ later . It is identified by element "<literal>sockets</literal>" which
+ may include one attribute "<literal>max</literal>" which specifies
+ the maximum number of sockets to be used by Pazpar2.
+ </para>
+ </refsect2>
<refsect2 id="config-file">
<title>file</title>
<para>
<?xml version="1.0" encoding="UTF-8"?>
<pazpar2 xmlns="http://www.indexdata.com/pazpar2/1.0">
-
+ <sockets max="400"/>
<file path=".:xsl"/>
<server>
<listen port="9004"/>
if (iochan_add(iochan_man, con->iochan))
{
yaz_log(YLOG_FATAL, "Out of connections");
+ iochan_destroy(con->iochan);
+ con->iochan = 0;
ZOOM_connection_destroy(con->link);
con->link = 0;
r = -1;
struct yaz_poll_fd *fds;
};
-iochan_man_t iochan_man_create(int no_threads)
+iochan_man_t iochan_man_create(int no_threads, int max_sockets)
{
iochan_man_t man = xmalloc(sizeof(*man));
man->channel_list = 0;
man->limit_fd = limit_data.rlim_cur - 200;
}
#endif
+ if (max_sockets)
+ man->limit_fd = max_sockets;
+ yaz_log(YLOG_LOG, "iochan max threads %d max sockets %d",
+ no_threads, max_sockets);
yaz_mutex_create(&man->iochan_mutex);
return man;
}
{
int r = 0, no_fds = 0;
IOCHAN p;
- chan->man = man;
yaz_log(man->log_level, "iochan_add : chan=%p channel list=%p", chan,
man->channel_list);
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)
+ {
+ if (p->fd >= 0)
+ no_fds++;
+ }
+ if (chan->fd > 0 && man->limit_fd > 0 && no_fds >= man->limit_fd)
+ {
r = -1;
+ yaz_log(YLOG_WARN, "max channels %d in use", no_fds);
+ }
else
{
+ chan->man = man;
chan->next = man->channel_list;
man->channel_list = chan;
}
return r;
}
+void iochan_destroy(IOCHAN chan)
+{
+ if (chan->man)
+ chan->destroyed = 1;
+ else
+ iochan_destroy_real(chan);
+}
+
IOCHAN iochan_create(int fd, IOC_CALLBACK cb, int flags, const char *name)
{
IOCHAN new_iochan;
} *IOCHAN;
-iochan_man_t iochan_man_create(int no_threads);
+iochan_man_t iochan_man_create(int no_threads, int max_sockets);
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);
+void iochan_destroy(IOCHAN chan);
-#define iochan_destroy(i) (void)((i)->destroyed = 1)
#define iochan_getfd(i) ((i)->fd)
#define iochan_setfd(i, d) ((i)->fd = d)
#define iochan_getdata(i) ((i)->data)
p->channel = c;
p->first_response = 1;
c->proxy = p;
- // We will add EVENT_OUTPUT below
p->iochan = iochan_create(sock, proxy_io, EVENT_INPUT, "http_proxy");
iochan_setdata(p->iochan, p);
- iochan_add(ser->iochan_man, p->iochan);
+ if (iochan_add(ser->iochan_man, p->iochan))
+ {
+ iochan_destroy(p->iochan);
+ xfree(p);
+ return -1;
+ }
}
// Do _not_ modify Host: header, just checking it's existence
c = iochan_create(s, http_io, EVENT_INPUT | EVENT_EXCEPT,
"http_session_socket");
-
ch = http_channel_create(server->http_server, host, server);
ch->iochan = c;
iochan_setdata(c, ch);
- iochan_add(server->iochan_man, c);
+ if (iochan_add(server->iochan_man, c))
+ {
+ http_channel_destroy(c);
+ }
}
/* Create a http-channel listener, syntax [host:]port */
return 1;
}
}
- server->http_server = http_server_create();
+ c = iochan_create(s, http_accept, EVENT_INPUT|EVENT_EXCEPT, "http_server");
+ if (iochan_add(server->iochan_man, c))
+ {
+ iochan_destroy(c);
+ return -1;
+ }
+
+ server->http_server = http_server_create();
server->http_server->record_file = record_file;
server->http_server->listener_socket = s;
-
- c = iochan_create(s, http_accept, EVENT_INPUT | EVENT_EXCEPT, "http_server");
iochan_setdata(c, server);
- iochan_add(server->iochan_man, c);
return 0;
}
struct conf_server *servers;
int no_threads;
+ int max_sockets;
WRBUF confdir;
char *path;
iochan_man_t iochan_man;
xmlFree(number);
}
}
+ else if (!strcmp((const char *) n->name, "sockets"))
+ {
+ xmlChar *number = xmlGetProp(n, (xmlChar *) "max");
+ if (number)
+ {
+ config->max_sockets = atoi((const char *) number);
+ xmlFree(number);
+ }
+ }
else if (!strcmp((const char *) n->name, "file"))
{
xmlChar *path = xmlGetProp(n, (xmlChar *) "path");
config->servers = 0;
config->path = nmem_strdup(nmem, ".");
config->no_threads = 0;
+ config->max_sockets = 0;
config->iochan_man = 0;
config->confdir = wrbuf_alloc();
{
struct conf_server *ser;
- conf->iochan_man = iochan_man_create(conf->no_threads);
+ conf->iochan_man = iochan_man_create(conf->no_threads, conf->max_sockets);
for (ser = conf->servers; ser; ser = ser->next)
{
WRBUF w;