HTTPS (almost) everywhere.
[metze/wireshark/wip.git] / epan / register.c
1 /* register.c
2  * Definitions for protocol registration
3  *
4  * Wireshark - Network traffic analyzer
5  * By Gerald Combs <gerald@wireshark.org>
6  * Copyright 1998 Gerald Combs
7  *
8  * SPDX-License-Identifier: GPL-2.0-or-later
9  */
10
11 #include "register-int.h"
12 #include "ws_attributes.h"
13
14 #include <glib.h>
15 #include "epan/dissectors/dissectors.h"
16
17 static const char *cur_cb_name = NULL;
18 // We could use g_atomic_pointer_set/get instead of a mutex, but that's
19 // currently (early 2018) invisible to TSAN.
20 static GMutex cur_cb_name_mtx;
21 static GAsyncQueue *register_cb_done_q;
22
23 #define CB_WAIT_TIME (150 * 1000) // microseconds
24
25 static void set_cb_name(const char *proto) {
26     g_mutex_lock(&cur_cb_name_mtx);
27     cur_cb_name = proto;
28     g_mutex_unlock(&cur_cb_name_mtx);
29 }
30
31 static void *
32 register_all_protocols_worker(void *arg _U_)
33 {
34     for (gulong i = 0; i < dissector_reg_proto_count; i++) {
35         set_cb_name(dissector_reg_proto[i].cb_name);
36         dissector_reg_proto[i].cb_func();
37     }
38
39     g_async_queue_push(register_cb_done_q, GINT_TO_POINTER(TRUE));
40     return NULL;
41 }
42
43 void
44 register_all_protocols(register_cb cb, gpointer cb_data)
45 {
46     const char *cb_name;
47     register_cb_done_q = g_async_queue_new();
48     gboolean called_back = FALSE;
49     GThread *rapw_thread;
50
51     rapw_thread = g_thread_new("register_all_protocols_worker", &register_all_protocols_worker, NULL);
52     while (!g_async_queue_timeout_pop(register_cb_done_q, CB_WAIT_TIME)) {
53         g_mutex_lock(&cur_cb_name_mtx);
54         cb_name = cur_cb_name;
55         g_mutex_unlock(&cur_cb_name_mtx);
56         if (cb && cb_name) {
57             cb(RA_REGISTER, cb_name, cb_data);
58             called_back = TRUE;
59         }
60     }
61     g_thread_join(rapw_thread);
62     if (cb && !called_back) {
63         cb(RA_REGISTER, "finished", cb_data);
64     }
65 }
66
67 static void *
68 register_all_protocol_handoffs_worker(void *arg _U_)
69 {
70     for (gulong i = 0; i < dissector_reg_handoff_count; i++) {
71         set_cb_name(dissector_reg_handoff[i].cb_name);
72         dissector_reg_handoff[i].cb_func();
73     }
74
75     g_async_queue_push(register_cb_done_q, GINT_TO_POINTER(TRUE));
76     return NULL;
77 }
78
79 void
80 register_all_protocol_handoffs(register_cb cb, gpointer cb_data)
81 {
82     cur_cb_name = NULL;
83     const char *cb_name;
84     gboolean called_back = FALSE;
85     GThread *raphw_thread;
86
87     raphw_thread = g_thread_new("register_all_protocol_handoffs_worker", &register_all_protocol_handoffs_worker, NULL);
88     while (!g_async_queue_timeout_pop(register_cb_done_q, CB_WAIT_TIME)) {
89         g_mutex_lock(&cur_cb_name_mtx);
90         cb_name = cur_cb_name;
91         g_mutex_unlock(&cur_cb_name_mtx);
92         if (cb && cb_name) {
93             cb(RA_HANDOFF, cb_name, cb_data);
94             called_back = TRUE;
95         }
96     }
97     g_thread_join(raphw_thread);
98     if (cb && !called_back) {
99         cb(RA_HANDOFF, "finished", cb_data);
100     }
101     g_async_queue_unref(register_cb_done_q);
102 }
103
104 gulong register_count(void)
105 {
106     return dissector_reg_proto_count + dissector_reg_handoff_count;
107 }
108
109 /*
110  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
111  *
112  * Local Variables:
113  * c-basic-offset: 4
114  * tab-width: 8
115  * indent-tabs-mode: nil
116  * End:
117  *
118  * vi: set shiftwidth=4 tabstop=8 expandtab:
119  * :indentSize=4:tabSize=8:noTabs=true:
120  */