1 diff -x '*~' -ur hotplug2-201/uevent.c hotplug2-201.patched/uevent.c
2 --- hotplug2-201/uevent.c 2009-12-09 20:44:14.000000000 +0200
3 +++ hotplug2-201.patched/uevent.c 2010-04-02 23:03:11.000000000 +0300
6 dest = xmalloc(sizeof(struct uevent_t));
7 dest->action = src->action;
8 + dest->seqnum = src->seqnum;
9 + dest->action_str = strdup(src->action_str);
10 dest->env_vars_c = src->env_vars_c;
11 dest->env_vars = xmalloc(sizeof(struct env_var_t) * dest->env_vars_c);
12 dest->plain_s = src->plain_s;
13 diff -x '*~' -ur hotplug2-201/workers/worker_fork.c hotplug2-201.patched/workers/worker_fork.c
14 --- hotplug2-201/workers/worker_fork.c 2010-04-03 17:02:15.000000000 +0300
15 +++ hotplug2-201.patched/workers/worker_fork.c 2010-04-03 17:04:27.000000000 +0300
17 #include "worker_fork.h"
19 static struct worker_fork_ctx_t *global_ctx;
20 +static struct worker_fork_uevent_t *uevent_list;
22 +static void worker_fork_uevent_free(struct worker_fork_uevent_t *node) {
23 + uevent_free(node->uevent);
27 +static void worker_fork_uevent_add(void *in_ctx, struct uevent_t *uevent) {
30 + struct worker_fork_ctx_t *ctx = in_ctx;
31 + struct worker_fork_uevent_t *node, *walker;
33 + node = malloc(sizeof (struct worker_fork_uevent_t));
34 + node->uevent = uevent_dup(uevent);
37 + if (!uevent_list) uevent_list = node;
40 + * Put events that need to fork first and in reverse order
42 + env = xmalloc(sizeof(char *) * node->uevent->env_vars_c);
43 + for (i = 0; i < node->uevent->env_vars_c; i++) {
44 + env[i] = alloc_env(node->uevent->env_vars[i].key, node->uevent->env_vars[i].value);
47 + if (ruleset_flags(&ctx->settings->rules, uevent) & FLAG_SLOW) {
48 + node->next = uevent_list;
52 + for (walker = uevent_list; walker->next; walker = walker->next);
53 + walker->next = node;
55 + for (i = 0; i < node->uevent->env_vars_c; i++) {
56 + unsetenv(node->uevent->env_vars[i].key);
63 +static void worker_fork_uevent_del(struct worker_fork_uevent_t *node) {
64 + struct worker_fork_uevent_t *walker;
66 + if (node == uevent_list) {
67 + uevent_list = node->next;
70 + for (walker = uevent_list; walker->next; walker = walker->next)
71 + if (walker->next == node) walker->next = node->next;
73 + worker_fork_uevent_free(node);
76 +static void worker_fork_uevent_empty(void) {
77 + struct worker_fork_uevent_t *walker;
79 + if (!uevent_list) return;
80 + for (walker = uevent_list; walker->next; walker = walker->next) worker_fork_uevent_free(walker);
85 * Destroys data structures related to the given child ID (not PID).
87 struct worker_fork_ctx_t *ctx;
92 ctx = malloc(sizeof(struct worker_fork_ctx_t));
94 ctx->children_count = 0;
99 + worker_fork_uevent_empty();
103 @@ -384,15 +450,26 @@
105 struct worker_fork_child_t *child;
106 struct worker_fork_ctx_t *ctx = in_ctx;
107 + struct worker_fork_uevent_t *node, *walker;
108 + event_seqnum_t seqnum;
110 + worker_fork_uevent_add(ctx, uevent);
111 + walker = uevent_list;
114 - * A big loop, because if we fail to process the event,
115 + * A big loop, because if we fail to process the events,
116 * we don't want to give up.
118 * TODO: Decide if we want to limit the number of attempts
119 * or set a time limit before reporting terminal failure.
123 + * If more events are waiting, return to receive them
125 + if (!seqnum_get(&seqnum) && seqnum > uevent->seqnum) break;
128 worker_fork_update_children(ctx);
132 * No child process is currently available.
135 - env = xmalloc(sizeof(char *) * uevent->env_vars_c);
136 - for (i = 0; i < uevent->env_vars_c; i++) {
137 - env[i] = alloc_env(uevent->env_vars[i].key, uevent->env_vars[i].value);
138 + env = xmalloc(sizeof(char *) * node->uevent->env_vars_c);
139 + for (i = 0; i < node->uevent->env_vars_c; i++) {
140 + env[i] = alloc_env(node->uevent->env_vars[i].key, node->uevent->env_vars[i].value);
145 * can execute them in the main process?
147 if (ctx->always_fork == 0 && ctx->settings->dumb == 0 &&
148 - (ruleset_flags(&ctx->settings->rules, uevent) & FLAG_MASK_SLOW) == 0) {
149 - action_perform(ctx->settings, uevent);
150 + (ruleset_flags(&ctx->settings->rules, node->uevent) & FLAG_MASK_SLOW) == 0) {
151 + action_perform(ctx->settings, node->uevent);
152 + walker = walker->next;
153 + worker_fork_uevent_del(node);
154 + if (walker) continue;
158 @@ -427,11 +507,11 @@
159 * We have to fork off a new child.
161 if (ctx->children_count < ctx->max_children ||
162 - (ruleset_flags(&ctx->settings->rules, uevent) & FLAG_SLOW))
163 + (ruleset_flags(&ctx->settings->rules, node->uevent) & FLAG_SLOW))
164 child = worker_fork_spawn(ctx);
166 - for (i = 0; i < uevent->env_vars_c; i++) {
167 - unsetenv(uevent->env_vars[i].key);
168 + for (i = 0; i < node->uevent->env_vars_c; i++) {
169 + unsetenv(node->uevent->env_vars[i].key);
177 - if (!worker_fork_relay_event(child->event_fd, uevent));
180 + if (worker_fork_relay_event(child->event_fd, node->uevent)) {
184 + walker = walker->next;
185 + worker_fork_uevent_del(node);
186 + if (walker) continue;
191 diff -x '*~' -ur hotplug2-201/workers/worker_fork.h hotplug2-201.patched/workers/worker_fork.h
192 --- hotplug2-201/workers/worker_fork.h 2009-12-09 20:44:13.000000000 +0200
193 +++ hotplug2-201.patched/workers/worker_fork.h 2010-04-03 01:00:24.000000000 +0300
195 struct settings_t *settings;
198 +struct worker_fork_uevent_t {
199 + struct uevent_t *uevent;
200 + struct worker_fork_uevent_t *next;