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
11 #include "register-int.h"
12 #include "ws_attributes.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
);
32 g_mutex_unlock(&cur_cb_name_mtx
);
36 register_all_protocols_worker(void *arg _U_
)
38 void *volatile error_message
= NULL
;
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
53 * The message gets freed by ENDTRY, so we must make a copy
56 error_message
= g_strdup(GET_MESSAGE
);
60 g_async_queue_push(register_cb_done_q
, GINT_TO_POINTER(true));
61 return (void *) error_message
;
65 register_all_protocols(register_cb cb
, void *cb_data
)
68 register_cb_done_q
= g_async_queue_new();
69 bool called_back
= false;
71 const char *error_message
;
73 rapw_thread
= g_thread_new("register_all_protocols_worker", ®ister_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
);
79 cb(RA_REGISTER
, cb_name
, cb_data
);
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
);
92 register_all_protocol_handoffs_worker(void *arg _U_
)
94 void *volatile error_message
= NULL
;
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
109 * The message gets freed by ENDTRY, so we must make a copy
112 error_message
= g_strdup(GET_MESSAGE
);
116 g_async_queue_push(register_cb_done_q
, GINT_TO_POINTER(true));
117 return (void *) error_message
;
121 register_all_protocol_handoffs(register_cb cb
, void *cb_data
)
124 bool called_back
= false;
125 GThread
*raphw_thread
;
126 const char *error_message
;
129 raphw_thread
= g_thread_new("register_all_protocol_handoffs_worker", ®ister_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
);
135 cb(RA_HANDOFF
, cb_name
, cb_data
);
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
159 * indent-tabs-mode: nil
162 * vi: set shiftwidth=4 tabstop=8 expandtab:
163 * :indentSize=4:tabSize=8:noTabs=true: