1 /* 2 * runqueue-example.c 3 * 4 * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org> 5 * 6 * Permission to use, copy, modify, and/or distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <stdbool.h> 20 #include <stdlib.h> 21 #include <stdio.h> 22 #include <unistd.h> 23 24 #include "uloop.h" 25 #include "runqueue.h" 26 27 static struct runqueue q; 28 29 struct sleeper { 30 int val; 31 bool kill; 32 struct uloop_timeout t; 33 struct runqueue_process proc; 34 }; 35 36 static void q_empty(struct runqueue *q) 37 { 38 fprintf(stderr, "All done!\n"); 39 uloop_end(); 40 } 41 42 static const char* sleeper_type(struct sleeper *s) 43 { 44 return s->kill ? "killer" : "sleeper"; 45 } 46 47 static void q_sleep_run(struct runqueue *q, struct runqueue_task *t) 48 { 49 struct sleeper *s = container_of(t, struct sleeper, proc.task); 50 char str[32]; 51 pid_t pid; 52 53 fprintf(stderr, "[%d/%d] start 'sleep %d' (%s)\n", q->running_tasks, 54 q->max_running_tasks, s->val, sleeper_type(s)); 55 56 pid = fork(); 57 if (pid < 0) 58 return; 59 60 if (pid) { 61 runqueue_process_add(q, &s->proc, pid); 62 return; 63 } 64 65 sprintf(str, "%d", s->val); 66 execlp("sleep", "sleep", str, NULL); 67 exit(1); 68 } 69 70 static void q_sleep_cancel(struct runqueue *q, struct runqueue_task *t, int type) 71 { 72 struct sleeper *s = container_of(t, struct sleeper, proc.task); 73 74 fprintf(stderr, "[%d/%d] cancel 'sleep %d' (%s)\n", q->running_tasks, 75 q->max_running_tasks, s->val, sleeper_type(s)); 76 runqueue_process_cancel_cb(q, t, type); 77 } 78 79 static void q_sleep_complete(struct runqueue *q, struct runqueue_task *p) 80 { 81 struct sleeper *s = container_of(p, struct sleeper, proc.task); 82 83 fprintf(stderr, "[%d/%d] finish 'sleep %d' (%s) \n", q->running_tasks, 84 q->max_running_tasks, s->val, sleeper_type(s)); 85 free(s); 86 } 87 88 static void my_runqueue_process_kill_cb(struct runqueue *q, struct runqueue_task *p) 89 { 90 struct sleeper *s = container_of(p, struct sleeper, proc.task); 91 92 fprintf(stderr, "[%d/%d] killing process (%s)\n", q->running_tasks, 93 q->max_running_tasks, sleeper_type(s)); 94 runqueue_process_kill_cb(q, p); 95 } 96 97 static void timer_cb(struct uloop_timeout *t) 98 { 99 struct sleeper *s = container_of(t, struct sleeper, t); 100 if (s->kill) 101 runqueue_task_kill(&s->proc.task); 102 } 103 104 static struct sleeper* create_sleeper(int val, const struct runqueue_task_type *type, bool kill) 105 { 106 struct sleeper *s = calloc(1, sizeof(*s)); 107 s->kill = kill; 108 s->t.cb = timer_cb; 109 s->proc.task.type = type; 110 s->proc.task.run_timeout = 500; 111 s->proc.task.complete = q_sleep_complete; 112 s->val = val; 113 114 return s; 115 } 116 117 static void add_sleeper(int val) 118 { 119 static const struct runqueue_task_type sleeper_type = { 120 .run = q_sleep_run, 121 .cancel = q_sleep_cancel, 122 .kill = runqueue_process_kill_cb, 123 }; 124 125 static const struct runqueue_task_type killer_type = { 126 .run = q_sleep_run, 127 .cancel = q_sleep_cancel, 128 .kill = my_runqueue_process_kill_cb, 129 }; 130 131 struct sleeper *k = create_sleeper(val, &killer_type, true); 132 uloop_timeout_set(&k->t, 10); 133 uloop_timeout_add(&k->t); 134 runqueue_task_add(&q, &k->proc.task, false); 135 136 struct sleeper *s = create_sleeper(val, &sleeper_type, false); 137 runqueue_task_add(&q, &s->proc.task, false); 138 } 139 140 int main(int argc, char **argv) 141 { 142 uloop_init(); 143 144 runqueue_init(&q); 145 q.empty_cb = q_empty; 146 q.max_running_tasks = 1; 147 148 if (argc > 1) 149 q.max_running_tasks = atoi(argv[1]); 150 151 add_sleeper(1); 152 add_sleeper(1); 153 add_sleeper(1); 154 155 uloop_run(); 156 uloop_done(); 157 158 return 0; 159 } 160
This page was automatically generated by LXR 0.3.1. • OpenWrt