s3-spoolssd: expand children pool when necessary
authorSimo Sorce <idra@samba.org>
Mon, 9 May 2011 09:37:29 +0000 (05:37 -0400)
committerAndreas Schneider <asn@samba.org>
Wed, 10 Aug 2011 16:14:03 +0000 (18:14 +0200)
Signed-off-by: Andreas Schneider <asn@samba.org>
source3/printing/spoolssd.c

index ab0ab236876fb011090409fcb6c3afc644c97930..99bdaf7883c2ce36db881b52672b8425ec4f2f87 100644 (file)
 #define SPOOLSS_SPAWN_RATE 5
 #define SPOOLSS_MIN_LIFE 60 /* 1 minute minimum life time */
 
+#define SPOOLSS_ALL_FINE 0x00
+#define SPOOLSS_NEW_MAX  0x01
+#define SPOLLSS_ENOSPC   0x02
+
 static int spoolss_min_children;
 static int spoolss_max_children;
 static int spoolss_spawn_rate;
+static int spoolss_prefork_status;
 
 static void spoolss_prefork_config(void)
 {
+       static int spoolss_prefork_config_init = false;
        const char *prefork_str;
        int min, max, rate;
        bool use_defaults = false;
        int ret;
 
+       if (!spoolss_prefork_config_init) {
+               spoolss_prefork_status = SPOOLSS_ALL_FINE;
+               spoolss_min_children = 0;
+               spoolss_max_children = 0;
+               spoolss_spawn_rate = 0;
+               spoolss_prefork_config_init = true;
+       }
+
        prefork_str = lp_parm_const_string(GLOBAL_SECTION_SNUM,
                                           "spoolssd", "prefork", "none");
        if (strcmp(prefork_str, "none") == 0) {
@@ -64,14 +78,18 @@ static void spoolss_prefork_config(void)
        }
 
        if (use_defaults) {
-               spoolss_min_children = SPOOLSS_MIN_CHILDREN;
-               spoolss_max_children = SPOOLSS_MAX_CHILDREN;
-               spoolss_spawn_rate = SPOOLSS_SPAWN_RATE;
-       } else {
-               spoolss_min_children = min;
-               spoolss_max_children = max;
-               spoolss_spawn_rate = rate;
+               min = SPOOLSS_MIN_CHILDREN;
+               max = SPOOLSS_MAX_CHILDREN;
+               rate = SPOOLSS_SPAWN_RATE;
+       }
+
+       if (max > spoolss_max_children && spoolss_max_children != 0) {
+               spoolss_prefork_status |= SPOOLSS_NEW_MAX;
        }
+
+       spoolss_min_children = min;
+       spoolss_max_children = max;
+       spoolss_spawn_rate = rate;
 }
 
 void start_spoolssd(struct tevent_context *ev_ctx,
@@ -584,6 +602,15 @@ static void spoolssd_check_children(struct tevent_context *ev_ctx,
 
        pfp = talloc_get_type_abort(pvt, struct prefork_pool);
 
+       if ((spoolss_prefork_status & SPOOLSS_NEW_MAX) &&
+           !(spoolss_prefork_status & SPOLLSS_ENOSPC)) {
+               ret = prefork_expand_pool(pfp, spoolss_max_children);
+               if (ret == ENOSPC) {
+                       spoolss_prefork_status |= SPOLLSS_ENOSPC;
+               }
+               spoolss_prefork_status &= ~SPOOLSS_NEW_MAX;
+       }
+
        active = prefork_count_active_children(pfp, &total);
 
        if (total - active < spoolss_spawn_rate) {