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