#include <signal.h>
#include <sys/wait.h>
#include <uv.h>
+#include <deque>
struct jobent {
struct client_data *client;
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;
}
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;
+ }
}
}
}
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)