summaryrefslogtreecommitdiff
path: root/mysys
diff options
context:
space:
mode:
authorVladislav Vaintroub <wlad@mariadb.com>2019-10-29 18:20:21 +0100
committerVladislav Vaintroub <wlad@mariadb.com>2019-11-15 16:50:22 +0100
commitad17c98dd5877ededb8ac3d4e0ac1f7beed5406c (patch)
treeb916c99f622d16afeac9bee2e6f004cfabb9dcf8 /mysys
parent786b004972e635eb23f631661ba9927562ee2f3f (diff)
downloadmariadb-git-ad17c98dd5877ededb8ac3d4e0ac1f7beed5406c.tar.gz
MDEV-16264 - prerequisite patch, periodic thr_timer
Threadpool will need a functionality for periodic thr_timer (the threadpool maintainence task is a timer that runs periodically). Also increase the stack size for the timer thread, 8k won't be enough.
Diffstat (limited to 'mysys')
-rw-r--r--mysys/thr_timer.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/mysys/thr_timer.c b/mysys/thr_timer.c
index 1532875d7f3..f87c1f75555 100644
--- a/mysys/thr_timer.c
+++ b/mysys/thr_timer.c
@@ -85,7 +85,7 @@ my_bool init_thr_timer(uint alloc_timers)
/* Create a thread to handle timers */
pthread_attr_init(&thr_attr);
pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS);
- pthread_attr_setstacksize(&thr_attr,8196);
+ pthread_attr_setstacksize(&thr_attr,64*1024);
thr_timer_inited= 1;
if (mysql_thread_create(key_thread_timer, &timer_thread, &thr_attr,
timer_handler, NULL))
@@ -141,6 +141,18 @@ void thr_timer_init(thr_timer_t *timer_data, void(*function)(void*),
DBUG_VOID_RETURN;
}
+/*
+ Make timer periodic
+
+ @param timer_data Timer structure
+ @param micro_seconds Period
+*/
+void thr_timer_set_period(thr_timer_t* timer_data, ulonglong micro_seconds)
+{
+ DBUG_ENTER("thr_timer_set_period");
+ timer_data->period= micro_seconds;
+ DBUG_VOID_RETURN;
+}
/*
Request timer after X milliseconds
@@ -240,18 +252,35 @@ static sig_handler process_timers(struct timespec *now)
{
void (*function)(void*);
void *func_arg;
+ my_bool is_periodic;
timer_data= (thr_timer_t*) queue_top(&timer_queue);
function= timer_data->func;
func_arg= timer_data->func_arg;
+ is_periodic= timer_data->period != 0;
timer_data->expired= 1; /* Mark expired */
/*
We remove timer before calling timer function to allow thread to
delete it's timer data any time.
+
+ Deleting timer inside the callback would not work
+ for periodic timers, they need to be removed from
+ queue prior to destroying timer_data.
*/
queue_remove_top(&timer_queue); /* Remove timer */
(*function)(func_arg); /* Inform thread of timeout */
+ /*
+ If timer is periodic, recalculate next expiration time, and
+ reinsert it into the queue.
+ */
+ if (is_periodic && timer_data->period)
+ {
+ set_timespec_nsec(timer_data->expire_time, timer_data->period * 1000);
+ timer_data->expired= 0;
+ queue_insert(&timer_queue, (uchar*)timer_data);
+ }
+
/* Check if next one has also expired */
timer_data= (thr_timer_t*) queue_top(&timer_queue);
if (cmp_timespec(timer_data->expire_time, (*now)) > 0)