Add support for client timed out ops

Just opens a dialog window.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
diff --git a/client.c b/client.c
index a84b92c..feb1eba 100644
--- a/client.c
+++ b/client.c
@@ -984,7 +984,7 @@
 	return flist_empty(&client->cmd_list) && ret;
 }
 
-static int fio_client_timed_out(void)
+static int fio_client_timed_out(struct client_ops *ops)
 {
 	struct fio_client *client;
 	struct flist_head *entry, *tmp;
@@ -1002,7 +1002,11 @@
 		if (!client_check_cmd_timeout(client, &tv))
 			continue;
 
-		log_err("fio: client %s timed out\n", client->hostname);
+		if (ops->timed_out)
+			ops->timed_out(client);
+		else
+			log_err("fio: client %s timed out\n", client->hostname);
+
 		remove_client(client);
 		ret = 1;
 	}
@@ -1055,7 +1059,7 @@
 				request_client_etas();
 				memcpy(&eta_tv, &tv, sizeof(tv));
 
-				if (fio_client_timed_out())
+				if (fio_client_timed_out(ops))
 					break;
 			}
 
diff --git a/client.h b/client.h
index ea29789..a68507f 100644
--- a/client.h
+++ b/client.h
@@ -56,6 +56,7 @@
 typedef void (*client_thread_status_display_op)(char *status_message, double perc);
 typedef void (*client_quit_op)(struct fio_client *);
 typedef void (*client_add_job_op)(struct fio_client *, struct fio_net_cmd *);
+typedef void (*client_timed_out)(struct fio_client *);
 
 struct client_ops {
 	client_text_op_func text_op;
@@ -66,6 +67,7 @@
 	client_probe_op probe;
 	client_quit_op quit;
 	client_add_job_op add_job;
+	client_timed_out timed_out;
 	int stay_connected;
 };
 
diff --git a/gfio.c b/gfio.c
index 9d781af..85e4378 100644
--- a/gfio.c
+++ b/gfio.c
@@ -320,6 +320,35 @@
 	gtk_label_set_text(GTK_LABEL(ui->eta.iodepth), tmp);
 }
 
+static void gfio_client_timed_out(struct fio_client *client)
+{
+	struct gui *ui = client->client_data;
+	GtkWidget *dialog, *label, *content;
+	char buf[256];
+
+	gdk_threads_enter();
+
+	gfio_set_connected(ui, 0);
+
+	sprintf(buf, "Client %s: timeout talking to server.\n", client->hostname);
+
+	dialog = gtk_dialog_new_with_buttons("Timed out!",
+			GTK_WINDOW(ui->window),
+			GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+			GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
+
+	content = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+	label = gtk_label_new((const gchar *) buf);
+	gtk_container_add(GTK_CONTAINER(content), label);
+	gtk_widget_show_all(dialog);
+	gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
+
+	gtk_dialog_run(GTK_DIALOG(dialog));
+	gtk_widget_destroy(dialog);
+
+	gdk_threads_leave();
+}
+
 struct client_ops gfio_client_ops = {
 	.text_op		= gfio_text_op,
 	.disk_util		= gfio_disk_util_op,
@@ -329,6 +358,7 @@
 	.probe			= gfio_probe_op,
 	.quit			= gfio_quit_op,
 	.add_job		= gfio_add_job_op,
+	.timed_out		= gfio_client_timed_out,
 	.stay_connected		= 1,
 };
 
@@ -340,9 +370,7 @@
 
 static void *job_thread(void *arg)
 {
-	printf("job thread starts\n");
 	fio_handle_clients(&gfio_client_ops);
-	printf("job thread exits\n");
 	return NULL;
 }
 
@@ -660,7 +688,7 @@
 	 * Without it, the update that happens in gfio_update_thread_status
 	 * doesn't really happen in a timely fashion, you need expose events
 	 */
-	if (!g_thread_supported ())
+	if (!g_thread_supported())
 		g_thread_init(NULL);
 	gdk_threads_init();