1 /* Copyright (c) 2018, 2021, Oracle and/or its affiliates.
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 Foundation,
21 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
22
23 #include "gcs_view_modification_notifier.h"
24 #include "plugin_psi.h"
25
26
Plugin_gcs_view_modification_notifier()27 Plugin_gcs_view_modification_notifier::Plugin_gcs_view_modification_notifier()
28 :view_changing(false), cancelled_view_change(false),
29 injected_view_modification(false), error(0)
30 {
31
32 mysql_cond_init(key_GR_COND_view_modification_wait, &wait_for_view_cond);
33 mysql_mutex_init(key_GR_LOCK_view_modification_wait, &wait_for_view_mutex,
34 MY_MUTEX_INIT_FAST);
35 }
36
~Plugin_gcs_view_modification_notifier()37 Plugin_gcs_view_modification_notifier::~Plugin_gcs_view_modification_notifier()
38 {
39 mysql_mutex_destroy(&wait_for_view_mutex);
40 mysql_cond_destroy(&wait_for_view_cond);
41 }
42
43 void
start_view_modification()44 Plugin_gcs_view_modification_notifier::start_view_modification()
45 {
46 mysql_mutex_lock(&wait_for_view_mutex);
47 view_changing= true;
48 cancelled_view_change= false;
49 injected_view_modification= false;
50 error= 0;
51 mysql_mutex_unlock(&wait_for_view_mutex);
52 }
53
54 void
start_injected_view_modification()55 Plugin_gcs_view_modification_notifier::start_injected_view_modification()
56 {
57 mysql_mutex_lock(&wait_for_view_mutex);
58 view_changing= true;
59 cancelled_view_change= false;
60 injected_view_modification= true;
61 error= 0;
62 mysql_mutex_unlock(&wait_for_view_mutex);
63 }
64
65 bool
is_injected_view_modification()66 Plugin_gcs_view_modification_notifier::is_injected_view_modification()
67 {
68 mysql_mutex_lock(&wait_for_view_mutex);
69 bool result= injected_view_modification;
70 mysql_mutex_unlock(&wait_for_view_mutex);
71 return result;
72 }
73
74 bool
is_view_modification_ongoing()75 Plugin_gcs_view_modification_notifier::is_view_modification_ongoing()
76 {
77 mysql_mutex_lock(&wait_for_view_mutex);
78 bool result = view_changing;
79 mysql_mutex_unlock(&wait_for_view_mutex);
80 return result;
81 }
82
83 void
end_view_modification()84 Plugin_gcs_view_modification_notifier::end_view_modification()
85 {
86 mysql_mutex_lock(&wait_for_view_mutex);
87 view_changing= false;
88 mysql_cond_broadcast(&wait_for_view_cond);
89 mysql_mutex_unlock(&wait_for_view_mutex);
90 }
91
92 void
cancel_view_modification(int error)93 Plugin_gcs_view_modification_notifier::cancel_view_modification(int error)
94 {
95 mysql_mutex_lock(&wait_for_view_mutex);
96 view_changing= false;
97 cancelled_view_change= true;
98 this->error= error;
99 mysql_cond_broadcast(&wait_for_view_cond);
100 mysql_mutex_unlock(&wait_for_view_mutex);
101 }
102
103 bool
is_cancelled()104 Plugin_gcs_view_modification_notifier::is_cancelled()
105 {
106 assert(view_changing == false);
107 return cancelled_view_change;
108 }
109
110 bool
wait_for_view_modification(long timeout)111 Plugin_gcs_view_modification_notifier::wait_for_view_modification(long timeout)
112 {
113 struct timespec ts;
114 int result= 0;
115
116 mysql_mutex_lock(&wait_for_view_mutex);
117
118 DBUG_EXECUTE_IF("group_replication_skip_wait_for_view_modification",
119 { view_changing= false; };);
120
121 while (view_changing && !cancelled_view_change)
122 {
123 set_timespec(&ts, timeout);
124 result=
125 mysql_cond_timedwait(&wait_for_view_cond, &wait_for_view_mutex, &ts);
126
127 if(result != 0) //It means that it broke by timeout or an error.
128 {
129 view_changing= false;
130 break;
131 }
132 }
133
134 DBUG_EXECUTE_IF("group_replication_force_view_modification_timeout",
135 { result= 1; };);
136 if (result != 0)
137 error= GROUP_REPLICATION_CONFIGURATION_ERROR;
138
139 mysql_mutex_unlock(&wait_for_view_mutex);
140
141 return (result != 0 || cancelled_view_change);
142 }
143
144 int
get_error()145 Plugin_gcs_view_modification_notifier::get_error()
146 {
147 assert(view_changing == false);
148 return error;
149 }
150