}
}
+#ifdef WIN32
+static void sig_break(int sig)
+{
+ struct thread_data *td;
+ int i;
+
+ sig_int(sig);
+
+ /**
+ * Windows terminates all job processes on SIGBREAK after the handler
+ * returns, so give them time to wrap-up and give stats
+ */
+ for_each_td(td, i) {
+ while (td->runstate < TD_EXITED)
+ sleep(1);
+ }
+}
+#endif
+
void sig_show_status(int sig)
{
show_running_run_stats();
/* Windows uses SIGBREAK as a quit signal from other applications */
#ifdef WIN32
memset(&act, 0, sizeof(act));
- act.sa_handler = sig_int;
+ act.sa_handler = sig_break;
act.sa_flags = SA_RESTART;
sigaction(SIGBREAK, &act, NULL);
#endif
for_each_td(td, i) {
print_status_init(td->thread_number - 1);
- if (!td->o.create_serialize) {
- /*
- * When operating on a single rile in parallel,
- * perform single-threaded early setup so that
- * when setup_files() does not run into issues
- * later.
- */
- if (!i && td->o.nr_files==1) {
- if (setup_shared_file(td)) {
- exit_value++;
- if (td->error)
- log_err("fio: pid=%d, err=%d/%s\n",
- (int) td->pid, td->error, td->verror);
- td_set_runstate(td, TD_REAPED);
- todo--;
- }
- }
+ if (!td->o.create_serialize)
continue;
- }
if (fio_verify_load_state(td))
goto reap;
strerror(ret));
} else {
pid_t pid;
- struct fio_file **files;
void *eo;
dprint(FD_PROCESS, "will fork\n");
- files = td->files;
eo = td->eo;
read_barrier();
pid = fork();
_exit(ret);
} else if (i == fio_debug_jobno)
*fio_debug_jobp = pid;
- // freeing previously allocated memory for files
- // this memory freed MUST NOT be shared between processes, only the pointer itself may be shared within TD
- free(files);
free(eo);
free(fd);
fd = NULL;