]> xenbits.xensource.com Git - people/liuw/rumprun.git/commitdiff
Fix bug that caused mayhem if a program called exit()
authorAntti Kantee <pooka@iki.fi>
Wed, 6 May 2015 21:52:37 +0000 (21:52 +0000)
committerAntti Kantee <pooka@iki.fi>
Wed, 6 May 2015 21:54:29 +0000 (21:54 +0000)
Essentially, we did not signal the rumprun main thread that a program
has exited.  Fix this by running the signalling code in a pthread
cleanup handler instead of when main() returns (which it obviously
never does in case someone calls {_,}exit())

lib/librumprun_base/rumprun.c

index 07853f808c9d810f76985811236a0c7d004a5427..609eb6443e22169cfdb92a4692689bf73b9d71de 100644 (file)
@@ -123,6 +123,20 @@ struct rumprunner {
 static LIST_HEAD(,rumprunner) rumprunners = LIST_HEAD_INITIALIZER(&rumprunners);
 static int rumprun_done;
 
+/* XXX: does not yet nuke any pthread that mainfun creates */
+static void
+releaseme(void *arg)
+{
+       struct rumprunner *rr = arg;
+
+       rr->rr_done = 1;
+
+       pthread_mutex_lock(&w_mtx);
+       rumprun_done++;
+       pthread_cond_broadcast(&w_cv);
+       pthread_mutex_unlock(&w_mtx);
+}
+
 static void *
 mainbouncer(void *arg)
 {
@@ -132,25 +146,21 @@ mainbouncer(void *arg)
 
        rump_pub_lwproc_rfork(RUMP_RFFDG);
 
+       pthread_cleanup_push(releaseme, rr);
+
        fprintf(stderr,"\n=== calling \"%s\" main() ===\n\n", progname);
        rv = rr->rr_mainfun(rr->rr_argc, rr->rr_argv);
        fflush(stdout);
        fprintf(stderr,"\n=== main() of \"%s\" returned %d ===\n",
            progname, rv);
 
+       pthread_cleanup_pop(1);
+
        /*
         * XXX: missing _netbsd_userlevel_fini().  See comment in
         * rumprun_boot()
         */
 
-       /* XXX: does not yet nuke any pthread that mainfun creates */
-       rr->rr_done = 1;
-
-       pthread_mutex_lock(&w_mtx);
-       rumprun_done++;
-       pthread_cond_broadcast(&w_cv);
-       pthread_mutex_unlock(&w_mtx);
-
        /* exit() calls rumprun_pub_lwproc_releaselwp() (via _exit()) */
        exit(rv);
 }