From: Egor Date: Thu, 5 Jun 2025 14:12:03 +0000 (+0300) Subject: job: use a deuque to store jobents X-Git-Url: https://git.patchysicp.xyz/?a=commitdiff_plain;h=707aea3a63d88c2ccf59dc031be58bcf168fd812;p=patchyircd.git job: use a deuque to store jobents --- diff --git a/src/job.cpp b/src/job.cpp index 4fcf160..3e5bdb0 100644 --- a/src/job.cpp +++ b/src/job.cpp @@ -7,6 +7,7 @@ #include #include #include +#include struct jobent { struct client_data *client; @@ -15,8 +16,8 @@ struct jobent { char *data; size_t len; }; -static struct jobent *jobtab; -static int joblen = 0, jobcap = 0; + +static std::deque jobq; static pid_t current_child = -1; static int current_result = 0; @@ -61,26 +62,31 @@ void job_fini(void) } void job_process(void) { - if (joblen && !jobtab[0].job && current_child == -1) { - jobtab[0].then(jobtab[0].client, current_result); - memmove(jobtab, jobtab+1, sizeof(struct jobent)*(joblen-1)); - joblen--; + if (!jobq.empty()) { + jobent &job = jobq.front(); + if (!job.job && current_child == -1) { + job.then(job.client, current_result); + jobq.pop_front(); + } } - if (joblen && jobtab[0].job) { - pid_t pid = fork(); - if (pid == -1) { - abortf("job_process: fork failed\n"); - } else if (pid == 0) { - int rv = jobtab[0].job(jobtab[0].client, jobtab[0].data, jobtab[0].len); - memset(jobtab[0].data, 0, jobtab[0].len); - _exit(rv); - } else { - current_child = pid; - memset(jobtab[0].data, 0, jobtab[0].len); - free(jobtab[0].data); - jobtab[0].data = 0; - jobtab[0].len = 0; - jobtab[0].job = 0; + if (!jobq.empty()) { + jobent &job = jobq.front(); + if (job.job) { + pid_t pid = fork(); + if (pid == -1) { + abortf("job_process: fork failed\n"); + } else if (pid == 0) { + int rv = job.job(job.client, job.data, job.len); + memset(job.data, 0, job.len); + _exit(rv); + } else { + current_child = pid; + memset(job.data, 0, job.len); + free(job.data); + job.data = 0; + job.len = 0; + job.job = 0; + } } } } @@ -90,30 +96,24 @@ void job_add(struct client_data *cl, jobproc_t job, contproc_t then, char *data, if (!job) return; struct jobent ent = { cl, job, then, data, len }; - if (joblen == jobcap) { - jobcap = jobcap == 0 ? 16 : jobcap * 2; - jobtab = (struct jobent *)realloc(jobtab, sizeof(struct jobent)*jobcap); - if (!jobtab) - abortf("job_add: allocation failure\n"); - } - jobtab[joblen++] = ent; + jobq.push_back(ent); } void job_kill(struct client_data *cl) { - struct jobent *p, *q; - p = q = jobtab; - if (joblen && jobtab[0].client == cl) + if (!jobq.empty() && jobq.front().client == cl) current_child = -1; - while (p < jobtab+joblen) { + auto p = jobq.begin(); + auto q = p; + while (p != jobq.end()) { if (p->client != cl) { - *q++ = *p; + *q++ = *p++; } else { memset(p->data, 0, p->len); free(p->data); + p++; } - p++; } - joblen = q-jobtab; + jobq.erase(q, jobq.end()); } static int job_password_check_job(struct client_data *cl, const char *data, size_t len)