[PATCH] Fix some wierd pthread/atexit interactions
authorNathan Scott <nathans@sgi.com>
Tue, 6 Sep 2005 06:46:31 +0000 (08:46 +0200)
committerJens Axboe <axboe@suse.de>
Tue, 6 Sep 2005 06:46:31 +0000 (08:46 +0200)
blktrace.c

index 3d7a6c6ec0e63f7234f9048e82af2f770b1eb342..bdcd26172ea3bc4cf59593e971065d07145628e0 100644 (file)
@@ -140,6 +140,8 @@ static int kill_running_trace;
 
 static pthread_mutex_t stdout_mutex = PTHREAD_MUTEX_INITIALIZER;
 
+static void exit_trace(int status);
+
 static int find_mask_map(char *string)
 {
        int i;
@@ -180,12 +182,6 @@ static void stop_trace(void)
        }
 }
 
-static void exit_trace(int status)
-{
-       stop_trace();
-       exit(status);
-}
-
 static void extract_data(struct thread_information *tip, char *ofn, int nb)
 {
        int ret, bytes_left;
@@ -345,6 +341,15 @@ static int start_threads(void)
        return ncpus;
 }
 
+static void close_thread(struct thread_information *tip)
+{
+       if (tip->fd != -1)
+               close(tip->fd);
+       if (tip->ofd != -1)
+               close(tip->ofd);
+       tip->fd = tip->ofd = -1;
+}
+
 static void stop_threads(void)
 {
        struct thread_information *tip = thread_information;
@@ -355,12 +360,26 @@ static void stop_threads(void)
 
                if (pthread_join(tip->thread, (void *) &ret))
                        perror("thread_join");
-
-               close(tip->fd);
-               close(tip->ofd);
+               close_thread(tip);
        }
 }
 
+static void stop_tracing(void)
+{
+       struct thread_information *tip = thread_information;
+       int i;
+
+       for (i = 0; i < ncpus; i++, tip++)
+               close_thread(tip);
+       stop_trace();
+}
+
+static void exit_trace(int status)
+{
+       stop_tracing();
+       exit(status);
+}
+
 static void show_stats(void)
 {
        int i;
@@ -486,7 +505,7 @@ int main(int argc, char *argv[])
        signal(SIGHUP, handle_sigint);
        signal(SIGTERM, handle_sigint);
 
-       atexit(stop_trace);
+       atexit(stop_tracing);
 
        while (!is_done())
                sleep(1);