aboutsummaryrefslogtreecommitdiffstats
path: root/ui/iface_lists.c
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 /ui/iface_lists.c
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>
Diffstat (limited to 'ui/iface_lists.c')
-rw-r--r--ui/iface_lists.c65
1 files changed, 38 insertions, 27 deletions
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