Trivial cleanups and whitespace change in Event Scheduler code.
A larger patch is to come, this is to exclude rudimentary changes from it.
This commit is contained in:
parent
f017117d84
commit
094612854d
@ -81,7 +81,7 @@ Event_queue_element_for_exec::~Event_queue_element_for_exec()
|
||||
|
||||
RETURN VALUE
|
||||
Address or NULL in case of error
|
||||
|
||||
|
||||
NOTE
|
||||
Created on THD's mem_root
|
||||
*/
|
||||
@ -174,7 +174,7 @@ Event_parse_data::init_body(THD *thd)
|
||||
while (body_begin < body_end)
|
||||
{
|
||||
|
||||
if ((*body_end == '\0') ||
|
||||
if ((*body_end == '\0') ||
|
||||
(my_isspace(thd->variables.character_set_client, *body_end)))
|
||||
{ /* consume NULs and meaningless whitespace */
|
||||
--body.length;
|
||||
@ -186,7 +186,7 @@ Event_parse_data::init_body(THD *thd)
|
||||
consume closing comments
|
||||
|
||||
This is arguably wrong, but it's the best we have until the parser is
|
||||
changed to be smarter. FIXME PARSER
|
||||
changed to be smarter. FIXME PARSER
|
||||
|
||||
See also the sp_head code, where something like this is done also.
|
||||
|
||||
@ -296,7 +296,7 @@ Event_parse_data::init_execute_at(THD *thd)
|
||||
|
||||
if (item_execute_at->fix_fields(thd, &item_execute_at))
|
||||
goto wrong_value;
|
||||
|
||||
|
||||
/* no starts and/or ends in case of execute_at */
|
||||
DBUG_PRINT("info", ("starts_null && ends_null should be 1 is %d",
|
||||
(starts_null && ends_null)));
|
||||
@ -702,7 +702,7 @@ Event_basic::load_string_fields(Field **fields, ...)
|
||||
ret= TRUE;
|
||||
break;
|
||||
}
|
||||
field_value->length= strlen(field_value->str);
|
||||
field_value->length= strlen(field_value->str);
|
||||
|
||||
field_name= (enum enum_events_table_field) va_arg(args, int);
|
||||
}
|
||||
@ -778,7 +778,7 @@ Event_timed::Event_timed():
|
||||
*/
|
||||
|
||||
Event_timed::~Event_timed()
|
||||
{
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@ -1382,7 +1382,6 @@ Event_queue_element::compute_next_execution_time()
|
||||
DBUG_PRINT("info", ("Dropped: %d", dropped));
|
||||
status= Event_queue_element::DISABLED;
|
||||
status_changed= TRUE;
|
||||
dropped= TRUE;
|
||||
|
||||
goto ret;
|
||||
}
|
||||
@ -1574,7 +1573,7 @@ Event_queue_element::mark_last_executed(THD *thd)
|
||||
|
||||
last_executed= (my_time_t) thd->query_start();
|
||||
last_executed_changed= TRUE;
|
||||
|
||||
|
||||
execution_count++;
|
||||
}
|
||||
|
||||
@ -1762,7 +1761,7 @@ Event_timed::get_create_event(THD *thd, String *buf)
|
||||
*/
|
||||
|
||||
int
|
||||
Event_job_data::get_fake_create_event(THD *thd, String *buf)
|
||||
Event_job_data::get_fake_create_event(String *buf)
|
||||
{
|
||||
DBUG_ENTER("Event_job_data::get_create_event");
|
||||
/* FIXME: "EVERY 3337 HOUR" is asking for trouble. */
|
||||
@ -1853,7 +1852,7 @@ done:
|
||||
RETURN VALUE
|
||||
0 success
|
||||
EVEX_COMPILE_ERROR error during compilation
|
||||
EVEX_MICROSECOND_UNSUP mysql.event was tampered
|
||||
EVEX_MICROSECOND_UNSUP mysql.event was tampered
|
||||
*/
|
||||
|
||||
int
|
||||
@ -1878,7 +1877,7 @@ Event_job_data::compile(THD *thd, MEM_ROOT *mem_root)
|
||||
|
||||
show_create.length(0);
|
||||
|
||||
switch (get_fake_create_event(thd, &show_create)) {
|
||||
switch (get_fake_create_event(&show_create)) {
|
||||
case EVEX_MICROSECOND_UNSUP:
|
||||
DBUG_RETURN(EVEX_MICROSECOND_UNSUP);
|
||||
case 0:
|
||||
@ -2043,7 +2042,7 @@ event_change_security_context(THD *thd, LEX_STRING user, LEX_STRING host,
|
||||
thd->security_ctx= &thd->main_security_ctx;
|
||||
#endif
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
@ -127,24 +127,6 @@ public:
|
||||
|
||||
bool
|
||||
update_timing_fields(THD *thd);
|
||||
|
||||
static void *operator new(size_t size)
|
||||
{
|
||||
void *p;
|
||||
DBUG_ENTER("Event_queue_element::new(size)");
|
||||
p= my_malloc(size, MYF(0));
|
||||
DBUG_PRINT("info", ("alloc_ptr: 0x%lx", (long) p));
|
||||
DBUG_RETURN(p);
|
||||
}
|
||||
|
||||
static void operator delete(void *ptr, size_t size)
|
||||
{
|
||||
DBUG_ENTER("Event_queue_element::delete(ptr,size)");
|
||||
DBUG_PRINT("enter", ("free_ptr: 0x%lx", (long) ptr));
|
||||
TRASH(ptr, size);
|
||||
my_free((gptr) ptr, MYF(0));
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -206,7 +188,7 @@ public:
|
||||
compile(THD *thd, MEM_ROOT *mem_root);
|
||||
private:
|
||||
int
|
||||
get_fake_create_event(THD *thd, String *buf);
|
||||
get_fake_create_event(String *buf);
|
||||
|
||||
Event_job_data(const Event_job_data &); /* Prevent use of these */
|
||||
void operator=(Event_job_data &);
|
||||
|
@ -142,7 +142,7 @@ const TABLE_FIELD_W_TYPE event_table_fields[ET_FIELD_COUNT] =
|
||||
EVEX_GENERAL_ERROR Bad data
|
||||
EVEX_GET_FIELD_FAILED Field count does not match. table corrupted?
|
||||
|
||||
DESCRIPTION
|
||||
DESCRIPTION
|
||||
Used both when an event is created and when it is altered.
|
||||
*/
|
||||
|
||||
@ -178,7 +178,7 @@ mysql_event_fill_row(THD *thd, TABLE *table, Event_parse_data *et,
|
||||
/*
|
||||
Change the SQL_MODE only if body was present in an ALTER EVENT and of course
|
||||
always during CREATE EVENT.
|
||||
*/
|
||||
*/
|
||||
if (et->body.str)
|
||||
{
|
||||
fields[ET_FIELD_SQL_MODE]->store((longlong)thd->variables.sql_mode, TRUE);
|
||||
@ -237,7 +237,7 @@ mysql_event_fill_row(THD *thd, TABLE *table, Event_parse_data *et,
|
||||
fields[ET_FIELD_TRANSIENT_INTERVAL]->set_null();
|
||||
fields[ET_FIELD_STARTS]->set_null();
|
||||
fields[ET_FIELD_ENDS]->set_null();
|
||||
|
||||
|
||||
TIME time;
|
||||
my_tz_UTC->gmt_sec_to_TIME(&time, et->execute_at);
|
||||
|
||||
@ -253,7 +253,7 @@ mysql_event_fill_row(THD *thd, TABLE *table, Event_parse_data *et,
|
||||
this is an error if the action is create. something is borked
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
((Field_timestamp *)fields[ET_FIELD_MODIFIED])->set_time();
|
||||
|
||||
if (et->comment.str)
|
||||
@ -323,12 +323,12 @@ Event_db_repository::index_read_for_db_for_i_s(THD *thd, TABLE *schema_table,
|
||||
ret= copy_event_to_schema_table(thd, schema_table, event_table);
|
||||
if (ret == 0)
|
||||
ret= event_table->file->index_next_same(event_table->record[0],
|
||||
key_buf, key_len);
|
||||
key_buf, key_len);
|
||||
} while (ret == 0);
|
||||
}
|
||||
DBUG_PRINT("info", ("Scan finished. ret=%d", ret));
|
||||
}
|
||||
event_table->file->ha_index_end();
|
||||
event_table->file->ha_index_end();
|
||||
/* ret is guaranteed to be != 0 */
|
||||
if (ret == HA_ERR_END_OF_FILE || ret == HA_ERR_KEY_NOT_FOUND)
|
||||
DBUG_RETURN(FALSE);
|
||||
@ -489,7 +489,7 @@ Event_db_repository::open_event_table(THD *thd, enum thr_lock_type lock_type,
|
||||
check_parse_params()
|
||||
thd Thread context
|
||||
parse_data Event's data
|
||||
|
||||
|
||||
RETURN VALUE
|
||||
FALSE OK
|
||||
TRUE Error (reported)
|
||||
@ -535,7 +535,7 @@ check_parse_params(THD *thd, Event_parse_data *parse_data)
|
||||
0 OK
|
||||
EVEX_GENERAL_ERROR Failure
|
||||
|
||||
DESCRIPTION
|
||||
DESCRIPTION
|
||||
Creates an event. Relies on mysql_event_fill_row which is shared with
|
||||
::update_event. The name of the event is inside "et".
|
||||
*/
|
||||
@ -630,7 +630,7 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data,
|
||||
handle it here
|
||||
*/
|
||||
if ((ret= mysql_event_fill_row(thd, table, parse_data, FALSE)))
|
||||
goto err;
|
||||
goto err;
|
||||
|
||||
/* Close active transaction only if We are going to modify disk */
|
||||
if (end_active_trans(thd))
|
||||
@ -647,7 +647,7 @@ ok:
|
||||
(void) mysql_change_db(thd, old_db.str, 1);
|
||||
/*
|
||||
This statement may cause a spooky valgrind warning at startup
|
||||
inside init_key_cache on my system (ahristov, 2006/08/10)
|
||||
inside init_key_cache on my system (ahristov, 2006/08/10)
|
||||
*/
|
||||
close_thread_tables(thd);
|
||||
DBUG_RETURN(FALSE);
|
||||
@ -914,14 +914,14 @@ Event_db_repository::drop_schema_events(THD *thd, LEX_STRING schema)
|
||||
*/
|
||||
|
||||
void
|
||||
Event_db_repository::drop_events_by_field(THD *thd,
|
||||
Event_db_repository::drop_events_by_field(THD *thd,
|
||||
enum enum_events_table_field field,
|
||||
LEX_STRING field_value)
|
||||
{
|
||||
int ret= 0;
|
||||
TABLE *table= NULL;
|
||||
READ_RECORD read_record_info;
|
||||
DBUG_ENTER("Event_db_repository::drop_events_by_field");
|
||||
DBUG_ENTER("Event_db_repository::drop_events_by_field");
|
||||
DBUG_PRINT("enter", ("field=%d field_value=%s", field, field_value.str));
|
||||
|
||||
if (open_event_table(thd, TL_WRITE, &table))
|
||||
|
@ -62,7 +62,7 @@ public:
|
||||
update_event(THD *thd, Event_parse_data *parse_data, LEX_STRING *new_dbname,
|
||||
LEX_STRING *new_name);
|
||||
|
||||
bool
|
||||
bool
|
||||
drop_event(THD *thd, LEX_STRING db, LEX_STRING name, bool drop_if_exists);
|
||||
|
||||
void
|
||||
@ -98,5 +98,5 @@ private:
|
||||
Event_db_repository(const Event_db_repository &);
|
||||
void operator=(Event_db_repository &);
|
||||
};
|
||||
|
||||
|
||||
#endif /* _EVENT_DB_REPOSITORY_H_ */
|
||||
|
@ -32,16 +32,6 @@
|
||||
#define LOCK_QUEUE_DATA() lock_data(SCHED_FUNC, __LINE__)
|
||||
#define UNLOCK_QUEUE_DATA() unlock_data(SCHED_FUNC, __LINE__)
|
||||
|
||||
struct event_queue_param
|
||||
{
|
||||
THD *thd;
|
||||
Event_queue *queue;
|
||||
pthread_mutex_t LOCK_loaded;
|
||||
pthread_cond_t COND_loaded;
|
||||
bool loading_finished;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Compares the execute_at members of two Event_queue_element instances.
|
||||
Used as callback for the prioritized queue when shifting
|
||||
@ -62,7 +52,7 @@ struct event_queue_param
|
||||
execute_at.second_part is not considered during comparison
|
||||
*/
|
||||
|
||||
static int
|
||||
static int
|
||||
event_queue_element_compare_q(void *vptr, byte* a, byte *b)
|
||||
{
|
||||
my_time_t lhs = ((Event_queue_element *)a)->execute_at;
|
||||
@ -183,7 +173,7 @@ Event_queue::deinit_queue()
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Adds an event to the queue.
|
||||
|
||||
SYNOPSIS
|
||||
@ -209,7 +199,7 @@ Event_queue::create_event(THD *thd, Event_queue_element *new_element)
|
||||
LOCK_QUEUE_DATA();
|
||||
queue_insert_safe(&queue, (byte *) new_element);
|
||||
dbug_dump_queue(thd->query_start());
|
||||
pthread_cond_broadcast(&COND_queue_state);
|
||||
pthread_cond_broadcast(&COND_queue_state);
|
||||
UNLOCK_QUEUE_DATA();
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
@ -256,7 +246,7 @@ Event_queue::update_event(THD *thd, LEX_STRING dbname, LEX_STRING name,
|
||||
{
|
||||
DBUG_PRINT("info", ("new event in the queue: 0x%lx", (long) new_element));
|
||||
queue_insert_safe(&queue, (byte *) new_element);
|
||||
pthread_cond_broadcast(&COND_queue_state);
|
||||
pthread_cond_broadcast(&COND_queue_state);
|
||||
}
|
||||
|
||||
dbug_dump_queue(thd->query_start());
|
||||
@ -287,7 +277,7 @@ Event_queue::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name)
|
||||
find_n_remove_event(dbname, name);
|
||||
dbug_dump_queue(thd->query_start());
|
||||
UNLOCK_QUEUE_DATA();
|
||||
|
||||
|
||||
/*
|
||||
We don't signal here because the scheduler will catch the change
|
||||
next time it wakes up.
|
||||
@ -309,7 +299,7 @@ Event_queue::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name)
|
||||
|
||||
RETURN VALUE
|
||||
>=0 Number of dropped events
|
||||
|
||||
|
||||
NOTE
|
||||
Expected is the caller to acquire lock on LOCK_event_queue
|
||||
*/
|
||||
@ -341,7 +331,7 @@ Event_queue::drop_matching_events(THD *thd, LEX_STRING pattern,
|
||||
i++;
|
||||
}
|
||||
/*
|
||||
We don't call pthread_cond_broadcast(&COND_queue_state);
|
||||
We don't call pthread_cond_broadcast(&COND_queue_state);
|
||||
If we remove the top event:
|
||||
1. The queue is empty. The scheduler will wake up at some time and
|
||||
realize that the queue is empty. If create_event() comes inbetween
|
||||
|
@ -34,7 +34,7 @@ public:
|
||||
|
||||
bool
|
||||
init_queue(THD *thd);
|
||||
|
||||
|
||||
void
|
||||
deinit_queue();
|
||||
|
||||
|
@ -240,7 +240,7 @@ event_scheduler_thread(void *arg)
|
||||
|
||||
|
||||
/*
|
||||
Function that executes an event in a child thread. Setups the
|
||||
Function that executes an event in a child thread. Setups the
|
||||
environment for the event execution and cleans after that.
|
||||
|
||||
SYNOPSIS
|
||||
@ -254,7 +254,7 @@ event_scheduler_thread(void *arg)
|
||||
pthread_handler_t
|
||||
event_worker_thread(void *arg)
|
||||
{
|
||||
THD *thd;
|
||||
THD *thd;
|
||||
Event_queue_element_for_exec *event= (Event_queue_element_for_exec *)arg;
|
||||
|
||||
thd= event->thd;
|
||||
@ -267,7 +267,7 @@ event_worker_thread(void *arg)
|
||||
|
||||
|
||||
/*
|
||||
Function that executes an event in a child thread. Setups the
|
||||
Function that executes an event in a child thread. Setups the
|
||||
environment for the event execution and cleans after that.
|
||||
|
||||
SYNOPSIS
|
||||
@ -458,7 +458,7 @@ Event_scheduler::start()
|
||||
scheduler_thd= new_thd;
|
||||
DBUG_PRINT("info", ("Setting state go RUNNING"));
|
||||
state= RUNNING;
|
||||
DBUG_PRINT("info", ("Forking new thread for scheduduler. THD: 0x%lx", (long) new_thd));
|
||||
DBUG_PRINT("info", ("Forking new thread for scheduler. THD: 0x%lx", (long) new_thd));
|
||||
if (pthread_create(&th, &connection_attrib, event_scheduler_thread,
|
||||
(void*)scheduler_param_value))
|
||||
{
|
||||
@ -525,7 +525,7 @@ Event_scheduler::run(THD *thd)
|
||||
"event_name=0x%lx", (long) event_name));
|
||||
if (event_name)
|
||||
{
|
||||
if ((res= execute_top(thd, event_name)))
|
||||
if ((res= execute_top(event_name)))
|
||||
break;
|
||||
}
|
||||
else
|
||||
@ -559,7 +559,7 @@ Event_scheduler::run(THD *thd)
|
||||
*/
|
||||
|
||||
bool
|
||||
Event_scheduler::execute_top(THD *thd, Event_queue_element_for_exec *event_name)
|
||||
Event_scheduler::execute_top(Event_queue_element_for_exec *event_name)
|
||||
{
|
||||
THD *new_thd;
|
||||
pthread_t th;
|
||||
@ -631,7 +631,7 @@ Event_scheduler::is_running()
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Stops the scheduler (again). Waits for acknowledgement from the
|
||||
scheduler that it has stopped - synchronous stopping.
|
||||
|
||||
@ -715,7 +715,7 @@ Event_scheduler::workers_count()
|
||||
{
|
||||
THD *tmp;
|
||||
uint count= 0;
|
||||
|
||||
|
||||
DBUG_ENTER("Event_scheduler::workers_count");
|
||||
pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
|
||||
I_List_iterator<THD> it(threads);
|
||||
|
@ -15,6 +15,12 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
/*
|
||||
This file is internal to Events module. Please do not include it directly.
|
||||
All public declarations of Events module are in events.h and
|
||||
event_data_objects.h.
|
||||
*/
|
||||
|
||||
|
||||
class Event_queue;
|
||||
class Event_job_data;
|
||||
@ -31,7 +37,7 @@ void
|
||||
deinit_event_thread(THD *thd);
|
||||
|
||||
|
||||
class Event_worker_thread
|
||||
class Event_worker_thread
|
||||
{
|
||||
public:
|
||||
static void
|
||||
@ -74,7 +80,7 @@ public:
|
||||
bool
|
||||
run(THD *thd);
|
||||
|
||||
void
|
||||
void
|
||||
init_scheduler(Event_queue *queue);
|
||||
|
||||
void
|
||||
@ -99,7 +105,7 @@ private:
|
||||
|
||||
/* helper functions */
|
||||
bool
|
||||
execute_top(THD *thd, Event_queue_element_for_exec *event_name);
|
||||
execute_top(Event_queue_element_for_exec *event_name);
|
||||
|
||||
/* helper functions for working with mutexes & conditionals */
|
||||
void
|
||||
|
@ -49,7 +49,7 @@
|
||||
counterpart.
|
||||
1. CREATE EVENT the_name ON SCHEDULE EVERY 1 SECOND DISABLE DO SELECT 1;
|
||||
2. DROP EVENT the_name
|
||||
|
||||
|
||||
In other words, the first one will create a row in mysql.event . In the
|
||||
second step because there will be a line, disk based drop will pass and
|
||||
the scheduler will remove the memory counterpart. The reason is that
|
||||
@ -309,7 +309,7 @@ Events::Events()
|
||||
TRUE Error (Reported)
|
||||
|
||||
NOTES
|
||||
In case there is an event with the same name (db) and
|
||||
In case there is an event with the same name (db) and
|
||||
IF NOT EXISTS is specified, an warning is put into the stack.
|
||||
*/
|
||||
|
||||
@ -346,7 +346,6 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, bool if_not_exists)
|
||||
pthread_mutex_unlock(&LOCK_event_metadata);
|
||||
|
||||
DBUG_RETURN(ret);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -364,7 +363,7 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, bool if_not_exists)
|
||||
TRUE Error
|
||||
|
||||
NOTES
|
||||
et contains data about dbname and event name.
|
||||
et contains data about dbname and event name.
|
||||
new_name is the new name of the event, if not null this means
|
||||
that RENAME TO was specified in the query
|
||||
*/
|
||||
@ -396,7 +395,7 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, sp_name *rename_to)
|
||||
new_element)))
|
||||
{
|
||||
DBUG_ASSERT(ret == OP_LOAD_ERROR);
|
||||
delete new_element;
|
||||
delete new_element;
|
||||
}
|
||||
else
|
||||
event_queue->update_event(thd, parse_data->dbname, parse_data->name,
|
||||
@ -444,7 +443,7 @@ Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Drops all events from a schema
|
||||
|
||||
SYNOPSIS
|
||||
@ -457,8 +456,8 @@ void
|
||||
Events::drop_schema_events(THD *thd, char *db)
|
||||
{
|
||||
LEX_STRING const db_lex= { db, strlen(db) };
|
||||
|
||||
DBUG_ENTER("Events::drop_schema_events");
|
||||
|
||||
DBUG_ENTER("Events::drop_schema_events");
|
||||
DBUG_PRINT("enter", ("dropping events from %s", db));
|
||||
if (unlikely(check_system_tables_error))
|
||||
{
|
||||
@ -697,7 +696,7 @@ Events::deinit()
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Inits Events mutexes
|
||||
|
||||
SYNOPSIS
|
||||
@ -755,7 +754,7 @@ Events::dump_internal_status()
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Starts execution of events by the scheduler
|
||||
|
||||
SYNOPSIS
|
||||
@ -912,7 +911,7 @@ Events::check_system_tables(THD *thd)
|
||||
|
||||
RETURN VALUE
|
||||
0 OK
|
||||
!0 Error (EVEX_OPEN_TABLE_FAILED, EVEX_MICROSECOND_UNSUP,
|
||||
!0 Error (EVEX_OPEN_TABLE_FAILED, EVEX_MICROSECOND_UNSUP,
|
||||
EVEX_COMPILE_ERROR) - in all these cases mysql.event was
|
||||
tampered.
|
||||
|
||||
|
@ -19,7 +19,6 @@ class sp_name;
|
||||
class Event_parse_data;
|
||||
class Event_db_repository;
|
||||
class Event_queue;
|
||||
class Event_queue_element;
|
||||
class Event_scheduler;
|
||||
|
||||
/* Return codes */
|
||||
@ -38,6 +37,10 @@ enum enum_events_error_code
|
||||
int
|
||||
sortcmp_lex_string(LEX_STRING s, LEX_STRING t, CHARSET_INFO *cs);
|
||||
|
||||
/**
|
||||
@class Events -- a facade to the functionality of the Event Scheduler.
|
||||
|
||||
*/
|
||||
|
||||
class Events
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user