1 #ifndef _EVENT_QUEUE_H_
2 #define _EVENT_QUEUE_H_
3 /* Copyright (c) 2004, 2021, Oracle and/or its affiliates.
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License, version 2.0,
7    as published by the Free Software Foundation.
8 
9    This program is also distributed with certain software (including
10    but not limited to OpenSSL) that is licensed under separate terms,
11    as designated in a particular file or component or in included license
12    documentation.  The authors of MySQL hereby grant you an additional
13    permission to link the program and your derivative works with the
14    separately licensed software that they have included with MySQL.
15 
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License, version 2.0, for more details.
20 
21    You should have received a copy of the GNU General Public License
22    along with this program; if not, write to the Free Software Foundation,
23    51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
24 
25 /**
26 
27   @addtogroup Event_Scheduler
28   @{
29 
30   @file event_queue.h
31 
32   Queue of events awaiting execution.
33 */
34 
35 #include "my_global.h"                          // uint
36 #include "mysql/mysql_lex_string.h"             // LEX_STRING
37 #include "my_time.h"                    /* my_time_t, interval_type */
38 
39 #include "event_data_objects.h"
40 #include "event_parse_data.h"
41 #include "priority_queue.h"
42 #include "malloc_allocator.h"
43 
44 #ifdef HAVE_PSI_INTERFACE
45 extern PSI_mutex_key key_LOCK_event_queue;
46 extern PSI_cond_key key_COND_queue_state;
47 #endif /* HAVE_PSI_INTERFACE */
48 
49 class Event_basic;
50 class Event_queue_element;
51 class Event_queue_element_for_exec;
52 
53 class THD;
54 
55 
56 /**
57   Compares the execute_at members of two Event_queue_element instances.
58   Used as compare operator for the prioritized queue when shifting
59   elements inside.
60 
61   SYNOPSIS
62     event_queue_element_compare_q()
63     @param left     First Event_queue_element object
64     @param right    Second Event_queue_element object
65 
66   @retval
67    -1   left->execute_at < right->execute_at
68     0   left->execute_at == right->execute_at
69     1   left->execute_at > right->execute_at
70 
71   @remark
72     execute_at.second_part is not considered during comparison
73 */
74 struct Event_queue_less
75 {
76   /// Maps compare function to strict weak ordering required by Priority_queue.
operatorEvent_queue_less77   bool operator()(Event_queue_element *left, Event_queue_element *right)
78   {
79     return event_queue_element_compare_q(left, right) > 0;
80   }
81 
event_queue_element_compare_qEvent_queue_less82   int event_queue_element_compare_q(Event_queue_element *left,
83                                     Event_queue_element *right)
84   {
85     if (left->status == Event_parse_data::DISABLED)
86       return right->status != Event_parse_data::DISABLED;
87 
88     if (right->status == Event_parse_data::DISABLED)
89       return 1;
90 
91     my_time_t lhs = left->execute_at;
92     my_time_t rhs = right->execute_at;
93     return (lhs < rhs ? -1 : (lhs > rhs ? 1 : 0));
94   }
95 };
96 
97 
98 /**
99   Queue of active events awaiting execution.
100 */
101 
102 class Event_queue
103 {
104 public:
105   Event_queue();
106   ~Event_queue();
107 
108   bool
109   init_queue(THD *thd);
110 
111   /* Methods for queue management follow */
112 
113   bool
114   create_event(THD *thd, Event_queue_element *new_element,
115                bool *created);
116 
117   void
118   update_event(THD *thd, LEX_STRING dbname, LEX_STRING name,
119                Event_queue_element *new_element);
120 
121   void
122   drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name);
123 
124   void
125   drop_schema_events(THD *thd, LEX_STRING schema);
126 
127   void
128   recalculate_activation_times(THD *thd);
129 
130   bool
131   get_top_for_execution_if_time(THD *thd,
132                                 Event_queue_element_for_exec **event_name);
133 
134 
135   void
136   dump_internal_status();
137 
138 private:
139   void
140   empty_queue();
141 
142   void
143   deinit_queue();
144   /* helper functions for working with mutexes & conditionals */
145   void
146   lock_data(const char *func, uint line);
147 
148   void
149   unlock_data(const char *func, uint line);
150 
151   void
152   cond_wait(THD *thd, struct timespec *abstime, const PSI_stage_info *stage,
153             const char *src_func, const char *src_file, uint src_line);
154 
155   void
156   find_n_remove_event(LEX_STRING db, LEX_STRING name);
157 
158 
159   void
160   drop_matching_events(THD *thd, LEX_STRING pattern,
161                        bool (*)(LEX_STRING, Event_basic *));
162 
163 
164   void
165   dbug_dump_queue(time_t now);
166 
167   /* LOCK_event_queue is the mutex which protects the access to the queue. */
168   mysql_mutex_t LOCK_event_queue;
169   mysql_cond_t COND_queue_state;
170 
171   /* The sorted queue with the Event_queue_element objects */
172   Priority_queue<Event_queue_element*,
173                  std::vector<Event_queue_element*,
174                              Malloc_allocator<Event_queue_element*> >,
175                  Event_queue_less>
176   queue;
177 
178   my_time_t next_activation_at;
179 
180   uint mutex_last_locked_at_line;
181   uint mutex_last_unlocked_at_line;
182   uint mutex_last_attempted_lock_at_line;
183   const char* mutex_last_locked_in_func;
184   const char* mutex_last_unlocked_in_func;
185   const char* mutex_last_attempted_lock_in_func;
186   bool mutex_queue_data_locked;
187   bool mutex_queue_data_attempting_lock;
188   bool waiting_on_cond;
189 };
190 /**
191   @} (End of group Event_Scheduler)
192 */
193 
194 #endif /* _EVENT_QUEUE_H_ */
195