]> PatchyGit - patchyircd.git/commitdiff
job: use a deuque to store jobents
authorEgor <egor@patchysicp.xyz>
Thu, 5 Jun 2025 14:12:03 +0000 (17:12 +0300)
committerEgor <egor@patchysicp.xyz>
Thu, 5 Jun 2025 14:12:03 +0000 (17:12 +0300)
src/job.cpp

index 4fcf160..3e5bdb0 100644 (file)
@@ -7,6 +7,7 @@
 #include <signal.h>
 #include <sys/wait.h>
 #include <uv.h>
+#include <deque>
 
 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<jobent> 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)