Fix potential crash in terminate_threads()
[fio.git] / fio.c
diff --git a/fio.c b/fio.c
index 2ee7dca..d345064 100644 (file)
--- a/fio.c
+++ b/fio.c
@@ -49,7 +49,7 @@ int nr_thread = 0;
 int shm_id = 0;
 int temp_stall_ts;
 
-static struct fio_sem *startup_sem;
+static struct fio_mutex *startup_mutex;
 static volatile int fio_abort;
 static int exit_value;
 
@@ -60,8 +60,8 @@ struct io_log *agg_io_log[2];
 
 static inline void td_set_runstate(struct thread_data *td, int runstate)
 {
-       dprint(FD_PROCESS, "%d: runstate %d -> %d\n", td->pid, td->runstate,
-                                                       runstate);
+       dprint(FD_PROCESS, "pid=%d: runstate %d -> %d\n", td->pid, td->runstate,
+                                                               runstate);
        td->runstate = runstate;
 }
 
@@ -73,13 +73,21 @@ static void terminate_threads(int group_id)
        for_each_td(td, i) {
                if (group_id == TERMINATE_ALL || groupid == td->groupid) {
                        dprint(FD_PROCESS, "setting terminate on %d\n",td->pid);
+
+                       td->terminate = 1;
+                       td->o.start_delay = 0;
+
                        /*
                         * if the thread is running, just let it exit
                         */
                        if (td->runstate < TD_RUNNING)
                                kill(td->pid, SIGQUIT);
-                       td->terminate = 1;
-                       td->o.start_delay = 0;
+                       else {
+                               struct ioengine_ops *ops = td->io_ops;
+
+                               if (ops && (ops->flags & FIO_SIGQUIT))
+                                       kill(td->pid, SIGQUIT);
+                       }
                }
        }
 }
@@ -571,12 +579,6 @@ sync_done:
                }
        }
 
-       /*
-        * stop job if we failed doing any IO
-        */
-       if ((td->this_io_bytes[0] + td->this_io_bytes[1]) == 0)
-               td->done = 1;
-
        if (td->o.fill_device && td->error == ENOSPC) {
                td->error = 0;
                td->terminate = 1;
@@ -599,6 +601,12 @@ sync_done:
                }
        } else
                cleanup_pending_aio(td);
+
+       /*
+        * stop job if we failed doing any IO
+        */
+       if ((td->this_io_bytes[0] + td->this_io_bytes[1]) == 0)
+               td->done = 1;
 }
 
 static void cleanup_io_u(struct thread_data *td)
@@ -639,11 +647,7 @@ static int init_io_u(struct thread_data *td)
        int i, max_units;
        char *p;
 
-       if (td->io_ops->flags & FIO_SYNCIO)
-               max_units = 1;
-       else
-               max_units = td->o.iodepth;
-
+       max_units = td->o.iodepth;
        max_bs = max(td->o.max_bs[DDIR_READ], td->o.max_bs[DDIR_WRITE]);
        td->orig_buffer_size = (unsigned long long) max_bs * (unsigned long long) max_units;
 
@@ -777,7 +781,10 @@ static int clear_io_state(struct thread_data *td)
 
        td->last_was_sync = 0;
 
-       if (td->o.time_based)
+       /*
+        * reset file done count if we are to start over
+        */
+       if (td->o.time_based || td->o.loops)
                td->nr_done_files = 0;
 
        for_each_file(td, f, i)
@@ -819,14 +826,14 @@ static void *thread_main(void *data)
        td->io_hist_tree = RB_ROOT;
 
        td_set_runstate(td, TD_INITIALIZED);
-       fio_sem_up(startup_sem);
-       fio_sem_down(td->mutex);
+       fio_mutex_up(startup_mutex);
+       fio_mutex_down(td->mutex);
 
        /*
-        * the ->mutex semaphore is now no longer used, close it to avoid
+        * the ->mutex mutex is now no longer used, close it to avoid
         * eating a file descriptor
         */
-       fio_sem_remove(td->mutex);
+       fio_mutex_remove(td->mutex);
 
        /*
         * May alter parameters that init_io_u() will use, so we need to
@@ -1021,7 +1028,11 @@ static void reap_threads(int *nr_running, int *t_rate, int *m_rate)
                else
                        realthreads++;
 
-               if (!td->pid || td->runstate == TD_REAPED)
+               if (!td->pid) {
+                       pending++;
+                       continue;
+               }
+               if (td->runstate == TD_REAPED)
                        continue;
                if (td->o.use_thread) {
                        if (td->runstate == TD_EXITED) {
@@ -1206,7 +1217,7 @@ static void run_threads(void)
                                        exit(ret);
                                }
                        }
-                       fio_sem_down(startup_sem);
+                       fio_mutex_down(startup_mutex);
                }
 
                /*
@@ -1261,7 +1272,7 @@ static void run_threads(void)
                        m_rate += td->o.ratemin;
                        t_rate += td->o.rate;
                        todo--;
-                       fio_sem_up(td->mutex);
+                       fio_mutex_up(td->mutex);
                }
 
                reap_threads(&nr_running, &t_rate, &m_rate);
@@ -1310,7 +1321,7 @@ int main(int argc, char *argv[])
                setup_log(&agg_io_log[DDIR_WRITE]);
        }
 
-       startup_sem = fio_sem_init(0);
+       startup_mutex = fio_mutex_init(0);
 
        set_genesis_time();
 
@@ -1326,6 +1337,6 @@ int main(int argc, char *argv[])
                }
        }
 
-       fio_sem_remove(startup_sem);
+       fio_mutex_remove(startup_mutex);
        return exit_value;
 }