1 /* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22
23 #include "xcom/xcom_interface.h"
24
25 #include <assert.h>
26 #include <stdlib.h>
27
28 #include "xcom/app_data.h"
29 #include "xcom/bitset.h"
30 #include "xcom/node_list.h"
31 #include "xcom/node_no.h"
32 #include "xcom/node_set.h"
33 #include "xcom/pax_msg.h"
34 #include "xcom/server_struct.h"
35 #include "xcom/simset.h"
36 #include "xcom/site_def.h"
37 #include "xcom/site_struct.h"
38 #include "xcom/synode_no.h"
39 #include "xcom/task.h"
40 #include "xcom/task_debug.h"
41 #include "xcom/xcom_base.h"
42 #include "xcom/xcom_cache.h"
43 #include "xcom/xcom_common.h"
44 #include "xcom/xcom_detector.h"
45 #include "xcom/xcom_profile.h"
46 #include "xcom/xcom_transport.h"
47 #include "xcom/xcom_vp_str.h"
48 #include "xdr_gen/xcom_vp.h"
49
50 static xcom_full_data_receiver xcom_full_receive_data;
51 static xcom_full_local_view_receiver xcom_full_receive_local_view;
52 static xcom_full_global_view_receiver xcom_full_receive_global_view;
53
54 static xcom_data_receiver xcom_receive_data;
55 static xcom_local_view_receiver xcom_receive_local_view;
56 static xcom_global_view_receiver xcom_receive_global_view;
57
58 /* purecov: begin deadcode */
set_xcom_full_data_receiver(xcom_full_data_receiver x)59 void set_xcom_full_data_receiver(xcom_full_data_receiver x) {
60 xcom_full_receive_data = x;
61 }
62 /* purecov: end */
63
64 /* purecov: begin deadcode */
set_xcom_full_local_view_receiver(xcom_full_local_view_receiver x)65 void set_xcom_full_local_view_receiver(xcom_full_local_view_receiver x) {
66 xcom_full_receive_local_view = x;
67 }
68 /* purecov: end */
69
70 /* purecov: begin deadcode */
set_xcom_full_global_view_receiver(xcom_full_global_view_receiver x)71 void set_xcom_full_global_view_receiver(xcom_full_global_view_receiver x) {
72 xcom_full_receive_global_view = x;
73 }
74 /* purecov: end */
75
set_xcom_data_receiver(xcom_data_receiver x)76 void set_xcom_data_receiver(xcom_data_receiver x) { xcom_receive_data = x; }
77
set_xcom_local_view_receiver(xcom_local_view_receiver x)78 void set_xcom_local_view_receiver(xcom_local_view_receiver x) {
79 xcom_receive_local_view = x;
80 }
81
set_xcom_global_view_receiver(xcom_global_view_receiver x)82 void set_xcom_global_view_receiver(xcom_global_view_receiver x) {
83 xcom_receive_global_view = x;
84 }
85
86 static xcom_config_receiver xcom_receive_config = 0;
87
88 /* purecov: begin deadcode */
set_xcom_config_receiver(xcom_config_receiver x)89 void set_xcom_config_receiver(xcom_config_receiver x) {
90 xcom_receive_config = x;
91 }
92 /* purecov: end */
93
94 xcom_logger xcom_log = NULL;
95 xcom_debugger xcom_debug = NULL;
96 xcom_debugger_check xcom_debug_check = NULL;
97 int64_t xcom_debug_options = GCS_DEBUG_NONE;
98
set_xcom_logger(xcom_logger x)99 void set_xcom_logger(xcom_logger x) { xcom_log = x; }
100
set_xcom_debugger(xcom_debugger x)101 void set_xcom_debugger(xcom_debugger x) { xcom_debug = x; }
102
set_xcom_debugger_check(xcom_debugger_check x)103 void set_xcom_debugger_check(xcom_debugger_check x) { xcom_debug_check = x; }
104
105 /* Deliver message to application */
106
deliver_to_app(pax_machine * pma,app_data_ptr app,delivery_status app_status)107 void deliver_to_app(pax_machine *pma, app_data_ptr app,
108 delivery_status app_status) {
109 site_def const *site = 0;
110 int full_doit = xcom_full_receive_data != 0;
111 int doit = (xcom_receive_data != 0 && app_status == delivery_ok);
112
113 if (app_status == delivery_ok) {
114 if (!pma) {
115 g_critical(
116 "A fatal error ocurred that prevents XCom from delivering a message "
117 "that achieved consensus. XCom cannot proceed without compromising "
118 "correctness. XCom will now crash.");
119 }
120 assert(pma && "pma must not be a null pointer");
121 }
122
123 if (!(full_doit || doit)) return;
124
125 IFDBG(D_NONE, FN; PTREXP(pma); PTREXP(app); NDBG(app_status, d);
126 COPY_AND_FREE_GOUT(dbg_app_data(app)));
127 if (pma)
128 site = find_site_def(pma->synode);
129 else
130 site = get_site_def();
131
132 while (app) {
133 if (app->body.c_t == app_type) { /* Decode application data */
134 if (full_doit) {
135 /* purecov: begin deadcode */
136 xcom_full_receive_data(site, pma, app, app_status);
137 /* purecov: end */
138 } else {
139 if (doit) {
140 u_int copy_len = 0;
141 char *copy = (char *)malloc(app->body.app_u_u.data.data_len);
142 if (copy == NULL) {
143 /* purecov: begin inspected */
144 G_ERROR("Unable to allocate memory for the received message.");
145 /* purecov: end */
146 } else {
147 memcpy(copy, app->body.app_u_u.data.data_val,
148 app->body.app_u_u.data.data_len);
149 copy_len = app->body.app_u_u.data.data_len;
150 }
151 ADD_DBG(D_EXEC, add_synode_event(pma->synode););
152
153 xcom_receive_data(pma->synode, detector_node_set(site), copy_len,
154 cache_get_last_removed(), copy);
155 } else {
156 /* purecov: begin deadcode */
157 G_TRACE("Data message was not delivered.");
158 /* purecov: end */
159 }
160 }
161 } else if (app_status == delivery_ok) {
162 G_ERROR("Data message has wrong type %s ",
163 cargo_type_to_str(app->body.c_t));
164 }
165 app = app->next;
166 }
167 }
168
169 /**
170 Deliver a view message
171 */
172
deliver_view_msg(site_def const * site)173 void deliver_view_msg(site_def const *site) {
174 if (site) {
175 if (xcom_full_receive_local_view) {
176 /* purecov: begin deadcode */
177 xcom_full_receive_local_view(site, detector_node_set(site));
178 /* purecov: end */
179 } else if (xcom_receive_local_view) {
180 xcom_receive_local_view(site->start, detector_node_set(site));
181 }
182 }
183 }
184
185 #ifdef SUPPRESS_DUPLICATE_VIEWS
186 static node_set delivered_node_set;
187 static site_def const *delivered_site;
188
not_duplicate_view(site_def const * site)189 static int not_duplicate_view(site_def const *site) {
190 int retval;
191 retval = !(site == delivered_site &&
192 equal_node_set(delivered_node_set, site->global_node_set));
193 delivered_site = site;
194 copy_node_set(&site->global_node_set, &delivered_node_set);
195 return retval;
196 }
197 #endif
198
deliver_global_view_msg(site_def const * site,synode_no message_id)199 void deliver_global_view_msg(site_def const *site, synode_no message_id) {
200 if (site) {
201 #ifdef SUPPRESS_DUPLICATE_VIEWS
202 if (not_duplicate_view(site)) {
203 #endif
204 if (xcom_full_receive_global_view) {
205 /* purecov: begin deadcode */
206 xcom_full_receive_global_view(site, message_id,
207 clone_node_set(site->global_node_set));
208 /* purecov: end */
209 } else if (xcom_receive_global_view) {
210 xcom_receive_global_view(site->start, message_id,
211 clone_node_set(site->global_node_set),
212 site->event_horizon);
213 }
214 #ifdef SUPPRESS_DUPLICATE_VIEWS
215 }
216 #endif
217 }
218 }
219
deliver_config(app_data_ptr a)220 void deliver_config(app_data_ptr a) {
221 if (xcom_receive_config) {
222 /* purecov: begin deadcode */
223 xcom_receive_config(a);
224 /* purecov: end */
225 }
226 }
227
deinit_xcom_interface()228 void deinit_xcom_interface() {
229 #ifdef SUPPRESS_DUPLICATE_VIEWS
230 free_node_set(&delivered_node_set);
231 #endif
232 }
233