Per-job timeouts. (#1310)
[beanstalkd.git] / reserve.c
blob84da0fb21bd4429444eaff063cb54ea25a9f8652
1 /* reserve.c - job reservations */
3 /* Copyright (C) 2007 Keith Rarick and Philotic Inc.
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "job.h"
20 #include "prot.h"
21 #include "reserve.h"
23 static unsigned int cur_reserved_ct = 0;
25 /* Doubly-linked list of connections with at least one reserved job. */
26 static struct conn running = { &running, &running, 0 };
28 void
29 reserve_job(conn c, job j)
31 j->deadline = time(NULL) + j->ttr;
32 cur_reserved_ct++; /* stats */
33 conn_insert(&running, c);
34 j->state = JOB_STATE_RESERVED;
35 job_insert(&c->reserved_jobs, j);
36 return reply_job(c, j, MSG_RESERVED);
39 int
40 has_reserved_job(conn c)
42 return job_list_any_p(&c->reserved_jobs);
45 /* return the reserved job with the earliest deadline,
46 * or NULL if there's no reserved job */
47 job
48 soonest_job(conn c)
50 job j, soonest = NULL;
52 for (j = c->reserved_jobs.next; j != &c->reserved_jobs; j = j->next) {
53 if (j->deadline <= (soonest ? : j)->deadline) soonest = j;
55 return soonest;
58 void
59 enqueue_reserved_jobs(conn c)
61 int r;
62 job j;
64 while (job_list_any_p(&c->reserved_jobs)) {
65 j = job_remove(c->reserved_jobs.next);
66 r = enqueue_job(j, 0);
67 if (!r) bury_job(j);
68 cur_reserved_ct--;
69 if (!job_list_any_p(&c->reserved_jobs)) conn_remove(c);
73 int
74 has_reserved_this_job(conn c, job needle)
76 job j;
78 for (j = c->reserved_jobs.next; j != &c->reserved_jobs; j = j->next) {
79 if (needle == j) return 1;
81 return 0;
84 static job
85 find_reserved_job_in_conn(conn c, unsigned long long int id)
87 job j;
89 for (j = c->reserved_jobs.next; j != &c->reserved_jobs; j = j->next) {
90 if (j->id == id) return j;
92 return NULL;
95 job
96 remove_reserved_job(conn c, unsigned long long int id)
98 return remove_this_reserved_job(c, find_reserved_job_in_conn(c, id));
101 /* j can be NULL */
103 remove_this_reserved_job(conn c, job j)
105 j = job_remove(j);
106 if (j) cur_reserved_ct--;
107 if (!job_list_any_p(&c->reserved_jobs)) conn_remove(c);
108 return j;
112 find_reserved_job_in_list(conn list, unsigned long long int id)
114 job j;
115 conn c;
117 for (c = list->next; c != list; c = c->next) {
118 j = find_reserved_job_in_conn(c, id);
119 if (j) return j;
121 return NULL;
125 find_reserved_job(unsigned long long int id)
127 return find_reserved_job_in_list(&running, id);
130 unsigned int
131 get_reserved_job_ct()
133 return cur_reserved_ct;