Further work
authorAdam Dickmeiss <adam@indexdata.dk>
Fri, 16 Oct 2015 17:08:19 +0000 (19:08 +0200)
committerAdam Dickmeiss <adam@indexdata.dk>
Fri, 16 Oct 2015 17:08:19 +0000 (19:08 +0200)
doc/pazpar2_conf.xml
etc/pazpar2.cfg.dist
src/connection.c
src/eventl.c
src/eventl.h
src/http.c
src/pazpar2_config.c

index 635a8ba..c90c931 100644 (file)
     in main thread).
    </para>
   </refsect2>
     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>
   <refsect2 id="config-file">
    <title>file</title>
    <para>
index 4ec5b08..30b588e 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <pazpar2 xmlns="http://www.indexdata.com/pazpar2/1.0">
 <?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"/>
   <file path=".:xsl"/>
   <server>
     <listen port="9004"/>
index c2c4bea..fbdaf79 100644 (file)
@@ -427,6 +427,8 @@ static int connection_connect(struct connection *con, iochan_man_t iochan_man)
     if (iochan_add(iochan_man, con->iochan))
     {
         yaz_log(YLOG_FATAL, "Out of connections");
     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;
         ZOOM_connection_destroy(con->link);
         con->link = 0;
         r = -1;
index da2f7f9..89138c2 100644 (file)
@@ -108,7 +108,7 @@ struct iochan_man_s {
     struct yaz_poll_fd *fds;
 };
 
     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;
 {
     iochan_man_t man = xmalloc(sizeof(*man));
     man->channel_list = 0;
@@ -129,6 +129,10 @@ iochan_man_t iochan_man_create(int no_threads)
         man->limit_fd = limit_data.rlim_cur - 200;
     }
 #endif
         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;
 }
     yaz_mutex_create(&man->iochan_mutex);
     return man;
 }
@@ -168,17 +172,23 @@ int iochan_add(iochan_man_t man, IOCHAN chan)
 {
     int r = 0, no_fds = 0;
     IOCHAN p;
 {
     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)
 
     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;
         r = -1;
+        yaz_log(YLOG_WARN, "max channels %d in use", no_fds);
+    }
     else
     {
     else
     {
+        chan->man = man;
         chan->next = man->channel_list;
         man->channel_list = chan;
     }
         chan->next = man->channel_list;
         man->channel_list = chan;
     }
@@ -186,6 +196,14 @@ int iochan_add(iochan_man_t man, IOCHAN chan)
     return r;
 }
 
     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_create(int fd, IOC_CALLBACK cb, int flags, const char *name)
 {
     IOCHAN new_iochan;
index 392b000..7fad3d3 100644 (file)
@@ -51,12 +51,12 @@ typedef struct iochan
 } *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);
 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)
 #define iochan_getfd(i) ((i)->fd)
 #define iochan_setfd(i, d) ((i)->fd = d)
 #define iochan_getdata(i) ((i)->data)
index 994a452..a4f0844 100644 (file)
@@ -796,11 +796,15 @@ static int http_proxy(struct http_request *rq)
         p->channel = c;
         p->first_response = 1;
         c->proxy = p;
         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);
 
         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
     }
 
     // Do _not_ modify Host: header, just checking it's existence
@@ -1219,11 +1223,13 @@ static void http_accept(IOCHAN i, int event)
     c = iochan_create(s, http_io, EVENT_INPUT | EVENT_EXCEPT,
                       "http_session_socket");
 
     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);
     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 */
 }
 
 /* Create a http-channel listener, syntax [host:]port */
@@ -1331,15 +1337,19 @@ int http_init(struct conf_server *server, const char *record_fname)
             return 1;
         }
     }
             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;
     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_setdata(c, server);
 
-    iochan_add(server->iochan_man, c);
     return 0;
 }
 
     return 0;
 }
 
index 2f60eb4..290a39a 100644 (file)
@@ -53,6 +53,7 @@ struct conf_config
     struct conf_server *servers;
 
     int no_threads;
     struct conf_server *servers;
 
     int no_threads;
+    int max_sockets;
     WRBUF confdir;
     char *path;
     iochan_man_t iochan_man;
     WRBUF confdir;
     char *path;
     iochan_man_t iochan_man;
@@ -1252,6 +1253,15 @@ static int parse_config(struct conf_config *config, xmlNode *root)
                 xmlFree(number);
             }
         }
                 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");
         else if (!strcmp((const char *) n->name, "file"))
         {
             xmlChar *path = xmlGetProp(n, (xmlChar *) "path");
@@ -1309,6 +1319,7 @@ struct conf_config *config_create(const char *fname)
     config->servers = 0;
     config->path = nmem_strdup(nmem, ".");
     config->no_threads = 0;
     config->servers = 0;
     config->path = nmem_strdup(nmem, ".");
     config->no_threads = 0;
+    config->max_sockets = 0;
     config->iochan_man = 0;
 
     config->confdir = wrbuf_alloc();
     config->iochan_man = 0;
 
     config->confdir = wrbuf_alloc();
@@ -1411,7 +1422,7 @@ int config_start_listeners(struct conf_config *conf,
 {
     struct conf_server *ser;
 
 {
     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;
     for (ser = conf->servers; ser; ser = ser->next)
     {
         WRBUF w;