sq epan/dissectors/pidl/rcg/rcg.cnf
[wireshark-sm.git] / epan / register.c
blob97d3e62692d131a2bbeca91da942c4440322c470
1 /* register.c
2 * Definitions for protocol registration
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
11 #include "register-int.h"
12 #include "ws_attributes.h"
14 #include <glib.h>
16 #include <epan/exceptions.h>
18 #include "epan/dissectors/dissectors.h"
20 static const char *cur_cb_name;
21 // We could use g_atomic_pointer_set/get instead of a mutex, but that causes
22 // a false positive with Clang and TSAN for GLib < 2.64.0 (Issue #17753):
23 // https://gitlab.gnome.org/GNOME/glib/-/issues/1843
24 static GMutex cur_cb_name_mtx;
25 static GAsyncQueue *register_cb_done_q;
27 #define CB_WAIT_TIME (150 * 1000) // microseconds
29 static void set_cb_name(const char *proto) {
30 g_mutex_lock(&cur_cb_name_mtx);
31 cur_cb_name = proto;
32 g_mutex_unlock(&cur_cb_name_mtx);
35 static void *
36 register_all_protocols_worker(void *arg _U_)
38 void *volatile error_message = NULL;
40 TRY {
41 for (unsigned long i = 0; i < dissector_reg_proto_count; i++) {
42 set_cb_name(dissector_reg_proto[i].cb_name);
43 dissector_reg_proto[i].cb_func();
46 CATCH(DissectorError) {
48 * This is probably a dissector, or something it calls,
49 * calling REPORT_DISSECTOR_ERROR() in a registration
50 * routine or something else outside the normal dissection
51 * code path.
53 * The message gets freed by ENDTRY, so we must make a copy
54 * of it.
56 error_message = g_strdup(GET_MESSAGE);
58 ENDTRY;
60 g_async_queue_push(register_cb_done_q, GINT_TO_POINTER(true));
61 return (void *) error_message;
64 void
65 register_all_protocols(register_cb cb, void *cb_data)
67 const char *cb_name;
68 register_cb_done_q = g_async_queue_new();
69 bool called_back = false;
70 GThread *rapw_thread;
71 const char *error_message;
73 rapw_thread = g_thread_new("register_all_protocols_worker", &register_all_protocols_worker, NULL);
74 while (!g_async_queue_timeout_pop(register_cb_done_q, CB_WAIT_TIME)) {
75 g_mutex_lock(&cur_cb_name_mtx);
76 cb_name = cur_cb_name;
77 g_mutex_unlock(&cur_cb_name_mtx);
78 if (cb && cb_name) {
79 cb(RA_REGISTER, cb_name, cb_data);
80 called_back = true;
83 error_message = (const char *) g_thread_join(rapw_thread);
84 if (error_message != NULL)
85 THROW_MESSAGE(DissectorError, error_message);
86 if (cb && !called_back) {
87 cb(RA_REGISTER, "finished", cb_data);
91 static void *
92 register_all_protocol_handoffs_worker(void *arg _U_)
94 void *volatile error_message = NULL;
96 TRY {
97 for (unsigned long i = 0; i < dissector_reg_handoff_count; i++) {
98 set_cb_name(dissector_reg_handoff[i].cb_name);
99 dissector_reg_handoff[i].cb_func();
102 CATCH(DissectorError) {
104 * This is probably a dissector, or something it calls,
105 * calling REPORT_DISSECTOR_ERROR() in a registration
106 * routine or something else outside the normal dissection
107 * code path.
109 * The message gets freed by ENDTRY, so we must make a copy
110 * of it.
112 error_message = g_strdup(GET_MESSAGE);
114 ENDTRY;
116 g_async_queue_push(register_cb_done_q, GINT_TO_POINTER(true));
117 return (void *) error_message;
120 void
121 register_all_protocol_handoffs(register_cb cb, void *cb_data)
123 const char *cb_name;
124 bool called_back = false;
125 GThread *raphw_thread;
126 const char *error_message;
128 set_cb_name(NULL);
129 raphw_thread = g_thread_new("register_all_protocol_handoffs_worker", &register_all_protocol_handoffs_worker, NULL);
130 while (!g_async_queue_timeout_pop(register_cb_done_q, CB_WAIT_TIME)) {
131 g_mutex_lock(&cur_cb_name_mtx);
132 cb_name = cur_cb_name;
133 g_mutex_unlock(&cur_cb_name_mtx);
134 if (cb && cb_name) {
135 cb(RA_HANDOFF, cb_name, cb_data);
136 called_back = true;
139 error_message = (const char *) g_thread_join(raphw_thread);
140 if (error_message != NULL)
141 THROW_MESSAGE(DissectorError, error_message);
142 if (cb && !called_back) {
143 cb(RA_HANDOFF, "finished", cb_data);
145 g_async_queue_unref(register_cb_done_q);
148 unsigned long register_count(void)
150 return dissector_reg_proto_count + dissector_reg_handoff_count;
154 * Editor modelines - https://www.wireshark.org/tools/modelines.html
156 * Local Variables:
157 * c-basic-offset: 4
158 * tab-width: 8
159 * indent-tabs-mode: nil
160 * End:
162 * vi: set shiftwidth=4 tabstop=8 expandtab:
163 * :indentSize=4:tabSize=8:noTabs=true: