Merge branch 'blr' into develop
Conflicts: client/maxadmin.c server/core/CMakeLists.txt server/core/dcb.c server/core/gateway.c server/core/poll.c server/core/test/CMakeLists.txt server/core/test/makefile server/include/poll.h server/modules/routing/debugcmd.c
This commit is contained in:
@ -24,11 +24,21 @@
|
||||
/**
|
||||
* @file housekeeper.c Provide a mechanism to run periodic tasks
|
||||
*
|
||||
* The housekeeper provides a mechanism to allow for tasks, function
|
||||
* calls basically, to be run on a tiem basis. A task may be run
|
||||
* repeatedly, with a given frequency (in seconds), or may be a one
|
||||
* shot task that will only be run once after a specified number of
|
||||
* seconds.
|
||||
*
|
||||
* The housekeeper also maintains a global variable, hkheartbeat, that
|
||||
* is incremented every 100ms.
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 29/08/14 Mark Riddoch Initial implementation
|
||||
* 22/10/14 Mark Riddoch Addition of one-shot tasks
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
@ -43,6 +53,7 @@ static HKTASK *tasks = NULL;
|
||||
static SPINLOCK tasklock = SPINLOCK_INIT;
|
||||
|
||||
static int do_shutdown = 0;
|
||||
unsigned long hkheartbeat = 0;
|
||||
|
||||
static void hkthread(void *);
|
||||
|
||||
@ -69,7 +80,7 @@ hkinit()
|
||||
* @param taskfn The function to call for the task
|
||||
* @param data Data to pass to the task function
|
||||
* @param frequency How often to run the task, expressed in seconds
|
||||
* @return Return the tiem in seconds when the task will be first run if the task was added, otherwise 0
|
||||
* @return Return the time in seconds when the task will be first run if the task was added, otherwise 0
|
||||
*/
|
||||
int
|
||||
hktask_add(char *name, void (*taskfn)(void *), void *data, int frequency)
|
||||
@ -88,6 +99,7 @@ HKTASK *task, *ptr;
|
||||
task->task = taskfn;
|
||||
task->data = data;
|
||||
task->frequency = frequency;
|
||||
task->type = HK_REPEATED;
|
||||
task->nextdue = time(0) + frequency;
|
||||
task->next = NULL;
|
||||
spinlock_acquire(&tasklock);
|
||||
@ -112,6 +124,61 @@ HKTASK *task, *ptr;
|
||||
return task->nextdue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a one-shot task to the housekeeper task list
|
||||
*
|
||||
* Task names must be unique.
|
||||
*
|
||||
* @param name The unique name for this housekeeper task
|
||||
* @param taskfn The function to call for the task
|
||||
* @param data Data to pass to the task function
|
||||
* @param when How many second until the task is executed
|
||||
* @return Return the time in seconds when the task will be first run if the task was added, otherwise 0
|
||||
*
|
||||
*/
|
||||
int
|
||||
hktask_oneshot(char *name, void (*taskfn)(void *), void *data, int when)
|
||||
{
|
||||
HKTASK *task, *ptr;
|
||||
|
||||
if ((task = (HKTASK *)malloc(sizeof(HKTASK))) == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ((task->name = strdup(name)) == NULL)
|
||||
{
|
||||
free(task);
|
||||
return 0;
|
||||
}
|
||||
task->task = taskfn;
|
||||
task->data = data;
|
||||
task->frequency = 0;
|
||||
task->type = HK_ONESHOT;
|
||||
task->nextdue = time(0) + when;
|
||||
task->next = NULL;
|
||||
spinlock_acquire(&tasklock);
|
||||
ptr = tasks;
|
||||
while (ptr && ptr->next)
|
||||
{
|
||||
if (strcmp(ptr->name, name) == 0)
|
||||
{
|
||||
spinlock_release(&tasklock);
|
||||
free(task->name);
|
||||
free(task);
|
||||
return 0;
|
||||
}
|
||||
ptr = ptr->next;
|
||||
}
|
||||
if (ptr)
|
||||
ptr->next = task;
|
||||
else
|
||||
tasks = task;
|
||||
spinlock_release(&tasklock);
|
||||
|
||||
return task->nextdue;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove a named task from the housekeepers task list
|
||||
*
|
||||
@ -171,12 +238,17 @@ HKTASK *ptr;
|
||||
time_t now;
|
||||
void (*taskfn)(void *);
|
||||
void *taskdata;
|
||||
int i;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (do_shutdown)
|
||||
return;
|
||||
thread_millisleep(1000);
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
if (do_shutdown)
|
||||
return;
|
||||
thread_millisleep(100);
|
||||
hkheartbeat++;
|
||||
}
|
||||
now = time(0);
|
||||
spinlock_acquire(&tasklock);
|
||||
ptr = tasks;
|
||||
@ -189,6 +261,8 @@ void *taskdata;
|
||||
taskdata = ptr->data;
|
||||
spinlock_release(&tasklock);
|
||||
(*taskfn)(taskdata);
|
||||
if (ptr->type == HK_ONESHOT)
|
||||
hktask_remove(ptr->name);
|
||||
spinlock_acquire(&tasklock);
|
||||
ptr = tasks;
|
||||
}
|
||||
@ -208,3 +282,33 @@ hkshutdown()
|
||||
{
|
||||
do_shutdown = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the tasks that are scheduled for the house keeper
|
||||
*
|
||||
* @param pdcb The DCB to send to output
|
||||
*/
|
||||
void
|
||||
hkshow_tasks(DCB *pdcb)
|
||||
{
|
||||
HKTASK *ptr;
|
||||
struct tm tm;
|
||||
char buf[40];
|
||||
|
||||
dcb_printf(pdcb, "%-25s | Type | Frequency | Next Due\n", "Name");
|
||||
dcb_printf(pdcb, "--------------------------+----------+-----------+-------------------------\n");
|
||||
spinlock_acquire(&tasklock);
|
||||
ptr = tasks;
|
||||
while (ptr)
|
||||
{
|
||||
localtime_r(&ptr->nextdue, &tm);
|
||||
asctime_r(&tm, buf);
|
||||
dcb_printf(pdcb, "%-25s | %-8s | %-9d | %s",
|
||||
ptr->name,
|
||||
ptr->type == HK_REPEATED ? "Repeated" : "One-Shot",
|
||||
ptr->frequency,
|
||||
buf);
|
||||
ptr = ptr->next;
|
||||
}
|
||||
spinlock_release(&tasklock);
|
||||
}
|
||||
|
Reference in New Issue
Block a user