Environment Reference Count Went Negative

Bron Gondwana brong at fastmail.fm
Mon Jul 27 02:44:06 EDT 2009


So this has been annoying me enough to track down the cause.

It's idled.  Specifically, the fork() after cyrus_init().
You can't do that.  It's broken.  If you want to fork then
you need to do it before cyrus_init() or you wind up cloning
the bdb environment and closing it twice.

Question for those who might know - why does idled fork so
late?  Well - first of all why does it fork at all rather
than being forked off by master - but following on from
that...

Anyway, the attached patch moves the fork before the
cyrus_init(), which solves the problem nicely for me.
I did consider just not calling cyrus_done in the parent
clean exit, but that seemed much more dangerous.

Bron.
-------------- next part --------------
diff --git a/imap/idled.c b/imap/idled.c
index e46d136..cd8f404 100644
--- a/imap/idled.c
+++ b/imap/idled.c
@@ -293,6 +293,22 @@ int main(int argc, char **argv)
 	}
     }
 
+    /* fork unless we were given the -d option */
+    if (debugmode == 0) {
+	
+	pid = fork();
+	
+	if (pid == -1) {
+	    perror("fork");
+	    exit(1);
+	}
+	
+	if (pid != 0) { /* parent */
+	    exit(0);
+	}
+    }
+    /* child */
+
     cyrus_init(alt_config, "idled", 0);
 
     /* get name of shutdown file */
@@ -354,24 +370,6 @@ int main(int argc, char **argv)
     umask(oldumask); /* for Linux */
     chmod(local.sun_path, 0777); /* for DUX */
 
-    /* fork unless we were given the -d option */
-    if (debugmode == 0) {
-	
-	pid = fork();
-	
-	if (pid == -1) {
-	    perror("fork");
-	    cyrus_done();
-	    exit(1);
-	}
-	
-	if (pid != 0) { /* parent */
-	    cyrus_done();
-	    exit(0);
-	}
-    }
-    /* child */
-
     /* get ready for select() */
     FD_ZERO(&read_set);
     FD_SET(s, &read_set);


More information about the Cyrus-devel mailing list