aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerald Combs <gerald@zing.org>2017-12-09 17:52:08 -0800
committerAnders Broman <a.broman58@gmail.com>2017-12-11 04:21:49 +0000
commit5b4894b7959f44e077f36194c490cbf402e1e659 (patch)
treea3540f3ae43d2950c364d61f613a5d6deb59d442
parent0d5ad701b494c29dd5ae5e44ecb5f9a42c423f5b (diff)
Move fill_in_local_interfaces to a thread.
Move fill_in_local_interfaces to a worker thread and start it as early as possible. Add a mutex for global_capture_opts. Change-Id: I09beab751c9c2917f017b6c082166d86ca693544 Reviewed-on: https://code.wireshark.org/review/24757 Reviewed-by: Gerald Combs <gerald@wireshark.org> Petri-Dish: Gerald Combs <gerald@wireshark.org> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
-rw-r--r--ui/capture_globals.h17
-rw-r--r--ui/commandline.c16
-rw-r--r--ui/gtk/main.c5
-rw-r--r--ui/gtk/main_welcome.c1
-rw-r--r--ui/iface_lists.c65
-rw-r--r--ui/iface_lists.h33
-rw-r--r--wireshark-qt.cpp40
7 files changed, 79 insertions, 98 deletions
diff --git a/ui/capture_globals.h b/ui/capture_globals.h
index 916bd37516..e71f29ade4 100644
--- a/ui/capture_globals.h
+++ b/ui/capture_globals.h
@@ -5,19 +5,7 @@
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __CAPTURE_GLOBALS_H__
@@ -29,7 +17,10 @@
extern "C" {
#endif /* __cplusplus */
+// This should probably be behind an API.
extern capture_options global_capture_opts;
+// Should this be an element of capture_options?
+extern GMutex global_capture_opts_mtx;
#ifdef __cplusplus
}
diff --git a/ui/commandline.c b/ui/commandline.c
index 8d81c8d1a9..f891fef5d0 100644
--- a/ui/commandline.c
+++ b/ui/commandline.c
@@ -5,19 +5,7 @@
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * SPDX-License-Identifier: GPL-2.0+
*/
#include "config.h"
@@ -66,6 +54,8 @@ commandline_param_info_t global_commandline_info;
#if defined(HAVE_LIBPCAP) || defined(HAVE_EXTCAP)
capture_options global_capture_opts;
+// Initialized in fill_in_local_interfaces_start.
+GMutex global_capture_opts_mtx;
#endif
void
diff --git a/ui/gtk/main.c b/ui/gtk/main.c
index 075f4995bf..2153a22a38 100644
--- a/ui/gtk/main.c
+++ b/ui/gtk/main.c
@@ -2172,6 +2172,7 @@ main(int argc, char *argv[])
capture_session_init(&global_capture_session, &cfile);
#endif
+ fill_in_local_interfaces_start();
init_report_message(vfailure_alert_box, vwarning_alert_box,
open_failure_alert_box, read_failure_alert_box,
@@ -2274,7 +2275,8 @@ main(int argc, char *argv[])
#ifdef HAVE_LIBPCAP
splash_update(RA_INTERFACES, NULL, (gpointer)splash_win);
- fill_in_local_interfaces(main_window_update);
+ fill_in_local_interfaces_wait(main_window_update);
+ g_mutex_lock(&global_capture_opts_mtx);
if (global_commandline_info.list_link_layer_types)
caps_queries |= CAPS_QUERY_LINK_TYPES;
@@ -2611,6 +2613,7 @@ main(int argc, char *argv[])
if (!global_commandline_info.start_capture && !global_capture_opts.default_options.cfilter) {
global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
}
+ g_mutex_unlock(&global_capture_opts_mtx);
#else /* HAVE_LIBPCAP */
show_main_window(FALSE);
check_and_warn_user_startup(global_commandline_info.cf_name);
diff --git a/ui/gtk/main_welcome.c b/ui/gtk/main_welcome.c
index 8ab92a6f4a..972552671d 100644
--- a/ui/gtk/main_welcome.c
+++ b/ui/gtk/main_welcome.c
@@ -1276,7 +1276,6 @@ welcome_new(void)
g_object_set_data(G_OBJECT(welcome_hb), CAPTURE_VIEW, topic_capture_to_fill);
#ifdef HAVE_LIBPCAP
- fill_in_local_interfaces(main_window_update);
fill_capture_box();
/* capture help topic */
diff --git a/ui/iface_lists.c b/ui/iface_lists.c
index a1b66745f1..e4294d2cd8 100644
--- a/ui/iface_lists.c
+++ b/ui/iface_lists.c
@@ -6,19 +6,7 @@
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * SPDX-License-Identifier: GPL-2.0+
*/
#include "config.h"
@@ -113,18 +101,14 @@ scan_local_interfaces(void (*update_cb)(void))
GString *ip_str;
interface_options *interface_opts;
gboolean found = FALSE;
- static gboolean running = FALSE;
GHashTable *selected_devices;
- if (running) {
- /* scan_local_interfaces internally calls update_cb to process UI events
- to avoid stuck UI while running possibly slow operations. A side effect
- of this is that new interface changes can be detected before completing
- the last one.
- This return avoids recursive scan_local_interfaces operation. */
- return;
- }
- running = TRUE;
+ /* scan_local_interfaces internally calls update_cb to process UI events
+ to avoid stuck UI while running possibly slow operations. A side effect
+ of this is that new interface changes can be detected before completing
+ the last one.
+ This return avoids recursive scan_local_interfaces operation. */
+ if (!g_mutex_trylock(&global_capture_opts_mtx)) return;
/*
* Clear list of known interfaces (all_ifaces) that will be re-discovered on
@@ -391,16 +375,21 @@ scan_local_interfaces(void (*update_cb)(void))
}
g_hash_table_destroy(selected_devices);
- running = FALSE;
+ g_mutex_unlock(&global_capture_opts_mtx);
}
+// XXX Copied from register.c
+#define CB_WAIT_TIME (150 * 1000) // microseconds
+static GThread *local_if_thread;
+static GAsyncQueue *local_interface_done_q;
+
/*
* Get the global interface list. Generate it if we haven't done so
* already. This can be quite time consuming the first time, so
* record how long it takes in the info log.
*/
-void
-fill_in_local_interfaces(void(*update_cb)(void))
+static void *
+fill_in_local_interfaces_worker(void *arg _U_)
{
GTimeVal start_time;
GTimeVal end_time;
@@ -413,7 +402,7 @@ fill_in_local_interfaces(void(*update_cb)(void))
if (!initialized) {
/* do the actual work */
- scan_local_interfaces(update_cb);
+ scan_local_interfaces(NULL);
initialized = TRUE;
}
/* log how long it took */
@@ -422,6 +411,28 @@ fill_in_local_interfaces(void(*update_cb)(void))
((end_time.tv_usec - start_time.tv_usec) / 1e6));
g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "fill_in_local_interfaces() ends, taking %.3fs", elapsed);
+ g_async_queue_push(local_interface_done_q, GINT_TO_POINTER(TRUE));
+ return NULL;
+}
+
+void
+fill_in_local_interfaces_start(void)
+{
+ if (!local_interface_done_q) {
+ g_mutex_init(&global_capture_opts_mtx);
+ local_interface_done_q = g_async_queue_new();
+ }
+ local_if_thread = g_thread_new("fill_in_local_interfaces_worker", &fill_in_local_interfaces_worker, NULL);
+}
+
+void
+fill_in_local_interfaces_wait(void(*update_cb)(void))
+{
+ while (!g_async_queue_timeout_pop(local_interface_done_q, CB_WAIT_TIME)) {
+ update_cb();
+ }
+ g_thread_join(local_if_thread);
+ local_if_thread = NULL;
}
void
diff --git a/ui/iface_lists.h b/ui/iface_lists.h
index 0c40f02f17..0c2738ff14 100644
--- a/ui/iface_lists.h
+++ b/ui/iface_lists.h
@@ -2,23 +2,7 @@
* Declarations of routines to manage the global list of interfaces and to
* update widgets/windows displaying items from those lists
*
- * Wireshark - Network traffic analyzer
- * By Gerald Combs <gerald@wireshark.org>
- * Copyright 1998 Gerald Combs
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __IFACE_LISTS_H__
@@ -36,15 +20,20 @@ extern "C" {
extern gint if_list_comparator_alph(const void *first_arg, const void *second_arg);
/*
- * Get the global interface list. Generate it if we haven't
- * done so already.
+ * Update the global interface list in the foreground.
+ */
+extern void scan_local_interfaces(void (*update_cb)(void));
+
+/*
+ * Update the global interface list in the background. Create it if we
+ * haven't done so already.
*/
-extern void fill_in_local_interfaces(void(*update_cb)(void));
+extern void fill_in_local_interfaces_start(void);
/*
- * Update the global interface list.
+ * Wait for the global interface list creation to finish.
*/
-extern void scan_local_interfaces(void (*update_cb)(void));
+extern void fill_in_local_interfaces_wait(void(*update_cb)(void));
/*
* Hide the interfaces
diff --git a/wireshark-qt.cpp b/wireshark-qt.cpp
index 059f2e0335..360ad10c37 100644
--- a/wireshark-qt.cpp
+++ b/wireshark-qt.cpp
@@ -469,6 +469,18 @@ int main(int argc, char *qt_argv[])
/* Assemble the run-time version information string */
runtime_info_str = get_runtime_version_info(get_wireshark_runtime_info);
+ /*
+ * Set the initial values in the capture options and fill in our
+ * interfaces. Options might be overwritten by preference settings
+ * and then again by the command line parameters. Interfaces might
+ * take a while to discover, so start discovering them as early as
+ * possible.
+ */
+#if defined(HAVE_LIBPCAP) || defined(HAVE_EXTCAP)
+ capture_opts_init(&global_capture_opts);
+#endif
+ fill_in_local_interfaces_start();
+
/* Create the user profiles directory */
if (create_profiles_dir(&rf_path) == -1) {
simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
@@ -549,6 +561,7 @@ int main(int argc, char *qt_argv[])
rf_path, g_strerror(rf_open_errno));
g_free(rf_path);
}
+
wsApp->applyCustomColorsFromRecent();
// Initialize our language
@@ -586,12 +599,6 @@ int main(int argc, char *qt_argv[])
g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "set_console_log_handler, elapsed time %" G_GUINT64_FORMAT " us \n", g_get_monotonic_time() - start_time);
#endif
-#ifdef HAVE_LIBPCAP
- /* Set the initial values in the capture options. This might be overwritten
- by preference settings and then again by the command line parameters. */
- capture_opts_init(&global_capture_opts);
-#endif
-
init_report_message(vfailure_alert_box, vwarning_alert_box,
open_failure_alert_box, read_failure_alert_box,
write_failure_alert_box);
@@ -696,10 +703,6 @@ int main(int argc, char *qt_argv[])
if (global_commandline_info.dfilter != NULL)
dfilter = QString(global_commandline_info.dfilter);
- /* Removed thread code:
- * https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=9e277ae6154fd04bf6a0a34ec5655a73e5a736a3
- */
-
timestamp_set_type(recent.gui_time_format);
timestamp_set_precision(recent.gui_time_precision);
timestamp_set_seconds_type (recent.gui_seconds_format);
@@ -710,11 +713,14 @@ int main(int argc, char *qt_argv[])
#endif
splash_update(RA_INTERFACES, NULL, NULL);
- fill_in_local_interfaces(main_window_update);
+ /* global_capture_opts_mtx isn't strictly necessary but it does make
+ * global_capture_opts' chain of custody a bit more obvious. */
+ fill_in_local_interfaces_wait(main_window_update);
+ g_mutex_lock(&global_capture_opts_mtx);
if (global_commandline_info.list_link_layer_types)
caps_queries |= CAPS_QUERY_LINK_TYPES;
- if (global_commandline_info.list_timestamp_types)
+ if (global_commandline_info.list_timestamp_types)
caps_queries |= CAPS_QUERY_TIMESTAMP_TYPES;
if (global_commandline_info.start_capture || caps_queries) {
@@ -818,31 +824,22 @@ int main(int argc, char *qt_argv[])
/* For update of WindowTitle (When use gui.window_title preference) */
main_w->setWSWindowTitle();
-////////
packet_list_enable_color(recent.packet_list_colorize);
g_log(NULL, G_LOG_LEVEL_DEBUG, "FIX: fetch recent color settings");
packet_list_enable_color(TRUE);
-////////
-
-
-////////
if (!color_filters_init(&err_msg, color_filter_add_cb)) {
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
g_free(err_msg);
}
-////////
-
#ifdef HAVE_LIBPCAP
/* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
if (!global_commandline_info.start_capture && !global_capture_opts.default_options.cfilter) {
global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
}
-#else /* HAVE_LIBPCAP */
- ////////
#endif /* HAVE_LIBPCAP */
wsApp->allSystemsGo();
@@ -922,6 +919,7 @@ int main(int argc, char *qt_argv[])
global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
}
}
+ g_mutex_unlock(&global_capture_opts_mtx);
#endif /* HAVE_LIBPCAP */
// UAT files used in configuration profiles which are used in Qt dialogs