+static int grant_new_job(void)
+{
+ int ret;
+ char byte = 0;
+
+ job_count++;
+ pr_info("Granting new job. %d jobs currently and %d pending\n",
+ job_count, jobs_pending);
+
+ ret = write(job_get_permission_fd[1], &byte, 1);
+ if (ret != 1) {
+ pr_err("Failed to write 1 byte: %m\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int handle_job_request(struct event_handler *h)
+{
+ int ret, pid;
+
+ ret = read(job_request_fd[0], &pid, sizeof(pid));
+ if (ret < 0) {
+ pr_err("Failed to read: %m\n");
+ return -1;
+ }
+
+ if (ret == 0) {
+ pr_info("Read zero bytes\n");
+ return 0;
+ }
+
+ if (pid > 0) {
+ if (job_count >= max_jobs) {
+ jobs_pending++;
+ } else {
+ ret = grant_new_job();
+ return 0;
+ }
+ } else if (pid < 0) {
+ if (job_count > max_jobs)
+ pr_err("BUG: Job %u jobs exceeded limit %u\n",
+ job_count, max_jobs);
+
+ pr_info("Job %d finished\n", -pid);
+ job_count--;
+ if (jobs_pending) {
+ jobs_pending--;
+ ret = grant_new_job();
+ return 0;
+ }
+ }
+
+ return 0;
+}
+
+struct event_handler signal_handler = {
+ .handle_event = handle_signals,
+ .events = EPOLLIN,
+ .name = "signal",
+};
+
+struct event_handler job_request_handler = {
+ .handle_event = handle_job_request,
+ .events = EPOLLIN,
+ .name = "job_request",
+};
+