merge job rusage and pending reason support

This commit is contained in:
Rongsong Shen 2025-12-16 14:36:28 +08:00
parent 30824ae5ea
commit cb0c7fe9e7
82 changed files with 4280 additions and 2561 deletions

192
src/lib/delay.c Normal file
View file

@ -0,0 +1,192 @@
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "delay.h"
#include "utils.h"
static void* delay_worker(void* args)
{
delaymgr_t* mgr = (delaymgr_t*)args;
while (1) {
ordq_item_t* it;
delay_task_t* t;
time_t now;
pthread_testcancel();
sleep(mgr->precision);
it = ordq_peek(&(mgr->tasks));
if (it == NULL) {
continue;
}
now = time(NULL);
if ((time_t)it->key > now) {
continue;
}
it = ordq_get(&(mgr->tasks));
t = (delay_task_t*)it->data;
mgr->runner_fn(t->entry, t->args);
if (t->runcount > 0) {
t->runcount--;
}
if (t->runcount == 0) {
FREEUP(t);
} else {
time_t nextrun = now + t->run_period;
/* put back to taskq as it need to be run again */
ordq_put(&(mgr->tasks), (void*)nextrun, t);
}
FREEUP(it);
}
return NULL;
}
static int time_cmp(time_t k1, time_t k2)
{
if (k1 > k2) {
return 1;
}
if (k1 == k2) {
return 0;
}
return -1;
}
static void delay_task_killer(delay_task_t* t)
{
if (t == NULL) {
return;
}
FREEUP(t);
}
static int default_runner_fn(delay_task_entry_fn_t entry, void* arg)
{
if (entry == NULL) {
return 0;
}
return entry(arg);
}
int delaymgr_init(delaymgr_t* mgr, int precision, task_run_fn_t runner_fn)
{
if ((mgr == NULL) || (precision <= 0)) {
return -EINVAL;
}
if (runner_fn == NULL) {
runner_fn = default_runner_fn;
}
mgr->precision = precision;
mgr->running = 0;
mgr->runner_fn = runner_fn;
mgr->worker = 0;
ordq_init(&(mgr->tasks), (ordq_data_killer_t)delay_task_killer,
(ordq_cmp_fn_t)time_cmp);
return 0;
}
void delaymgr_stop(delaymgr_t* mgr)
{
int rc;
if (mgr == NULL) {
return;
}
if (!(mgr->running)) {
return;
}
if (mgr->worker != 0) {
rc = pthread_cancel(mgr->worker);
if (rc == 0) {
void* res = NULL;
pthread_join(mgr->worker, &res);
if (res == PTHREAD_CANCELED) {
mgr->worker = 0;
}
}
}
return;
}
void delaymgr_fini(delaymgr_t* mgr)
{
if (mgr == NULL) {
return;
}
if (mgr->running) {
delaymgr_stop(mgr);
}
ordq_fini(&(mgr->tasks));
}
int delaymgr_start(delaymgr_t* mgr)
{
int rc;
if (mgr == NULL) {
return -EINVAL;
}
rc = pthread_create(&(mgr->worker), NULL, &delay_worker, mgr);
if (rc == 0) {
mgr->running = 1;
} else {
SET_ERROR(errno);
return -errno;
}
return 0;
}
int delay_task(delaymgr_t* mgr, int delay, int runcount,
delay_task_entry_fn_t entry, void* args)
{
delay_task_t* t;
time_t now = time(NULL);
time_t ts_nextrun;
if ((mgr == NULL) || (delay <= 0) || (entry == NULL)) {
return -EINVAL;
}
t = (delay_task_t*)calloc(1, sizeof(*t));
if (t == NULL) {
return -ENOMEM;
}
ts_nextrun = now + delay;
t->runcount = runcount;
t->run_period = delay;
t->entry = entry;
t->args = args;
return ordq_put(&(mgr->tasks), (void*)ts_nextrun, t);
}