diff options
Diffstat (limited to 'src/util/child_management.c')
-rw-r--r-- | src/util/child_management.c | 66 |
1 files changed, 35 insertions, 31 deletions
diff --git a/src/util/child_management.c b/src/util/child_management.c index 3afd682b9..832e05ece 100644 --- a/src/util/child_management.c +++ b/src/util/child_management.c | |||
@@ -19,7 +19,7 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | /** | 21 | /** |
22 | * @file testing/child_management.c | 22 | * @file util/child_management.c |
23 | * @brief Handling of child processes in GNUnet. | 23 | * @brief Handling of child processes in GNUnet. |
24 | * @author Christian Grothoff (ANASTASIS) | 24 | * @author Christian Grothoff (ANASTASIS) |
25 | * @author Dominik Meister (ANASTASIS) | 25 | * @author Dominik Meister (ANASTASIS) |
@@ -91,15 +91,10 @@ maint_child_death (void *cls) | |||
91 | 91 | ||
92 | (void) cls; | 92 | (void) cls; |
93 | sig_task = NULL; | 93 | sig_task = NULL; |
94 | |||
95 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
96 | "Received SIGCHLD.\n"); | ||
97 | |||
98 | /* drain pipe */ | 94 | /* drain pipe */ |
99 | pr = GNUNET_DISK_pipe_handle (sigpipe, | 95 | pr = GNUNET_DISK_pipe_handle (sigpipe, |
100 | GNUNET_DISK_PIPE_END_READ); | 96 | GNUNET_DISK_PIPE_END_READ); |
101 | GNUNET_assert (! GNUNET_DISK_handle_invalid (pr)); | 97 | GNUNET_assert (! GNUNET_DISK_handle_invalid (pr)); |
102 | |||
103 | (void) GNUNET_DISK_file_read (pr, | 98 | (void) GNUNET_DISK_file_read (pr, |
104 | buf, | 99 | buf, |
105 | sizeof(buf)); | 100 | sizeof(buf)); |
@@ -158,10 +153,11 @@ sighandler_child_death (void) | |||
158 | errno = old_errno; /* restore errno */ | 153 | errno = old_errno; /* restore errno */ |
159 | } | 154 | } |
160 | 155 | ||
161 | 156 | /** | |
162 | // void __attribute__ ((constructor)) | 157 | * Initializing the signal pipe for child handling. |
158 | */ | ||
163 | static void | 159 | static void |
164 | child_management_start () | 160 | child_management_start (void) |
165 | { | 161 | { |
166 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 162 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
167 | "Trying to start child management.\n"); | 163 | "Trying to start child management.\n"); |
@@ -170,19 +166,24 @@ child_management_start () | |||
170 | sigpipe = GNUNET_DISK_pipe (GNUNET_DISK_PF_NONE); | 166 | sigpipe = GNUNET_DISK_pipe (GNUNET_DISK_PF_NONE); |
171 | GNUNET_assert (sigpipe != NULL); | 167 | GNUNET_assert (sigpipe != NULL); |
172 | shc_chld = | 168 | shc_chld = |
173 | GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD, &sighandler_child_death); | 169 | GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD, |
170 | &sighandler_child_death); | ||
174 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 171 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
175 | "Child management started.\n"); | 172 | "Child management started.\n"); |
176 | } | 173 | } |
177 | 174 | ||
175 | |||
178 | /** | 176 | /** |
179 | * Clean up. | 177 | * Clean up. |
180 | */ | 178 | */ |
181 | // void __attribute__ ((destructor)) | ||
182 | static void | 179 | static void |
183 | child_management_done () | 180 | child_management_done (void) |
184 | { | 181 | { |
185 | GNUNET_assert (NULL == sig_task); | 182 | if (NULL != sig_task) |
183 | { | ||
184 | GNUNET_SCHEDULER_cancel (sig_task); | ||
185 | sig_task = NULL; | ||
186 | } | ||
186 | GNUNET_SIGNAL_handler_uninstall (shc_chld); | 187 | GNUNET_SIGNAL_handler_uninstall (shc_chld); |
187 | shc_chld = NULL; | 188 | shc_chld = NULL; |
188 | GNUNET_DISK_pipe_close (sigpipe); | 189 | GNUNET_DISK_pipe_close (sigpipe); |
@@ -191,6 +192,15 @@ child_management_done () | |||
191 | "Child management stopped.\n"); | 192 | "Child management stopped.\n"); |
192 | } | 193 | } |
193 | 194 | ||
195 | |||
196 | /** | ||
197 | * Adding a child process to be monitored by the child management. | ||
198 | * | ||
199 | * @param proc The child process to be monitored. | ||
200 | * @param cp The callback to be called, when the child process completed. | ||
201 | * @param cb_cls The closure for the callback. | ||
202 | * @return An handle for the the child being monitored. | ||
203 | */ | ||
194 | struct GNUNET_ChildWaitHandle * | 204 | struct GNUNET_ChildWaitHandle * |
195 | GNUNET_wait_child (struct GNUNET_OS_Process *proc, | 205 | GNUNET_wait_child (struct GNUNET_OS_Process *proc, |
196 | GNUNET_ChildCompletedCallback cb, | 206 | GNUNET_ChildCompletedCallback cb, |
@@ -198,9 +208,6 @@ GNUNET_wait_child (struct GNUNET_OS_Process *proc, | |||
198 | { | 208 | { |
199 | struct GNUNET_ChildWaitHandle *cwh; | 209 | struct GNUNET_ChildWaitHandle *cwh; |
200 | 210 | ||
201 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
202 | "Adding child!\n"); | ||
203 | |||
204 | child_management_start (); | 211 | child_management_start (); |
205 | cwh = GNUNET_new (struct GNUNET_ChildWaitHandle); | 212 | cwh = GNUNET_new (struct GNUNET_ChildWaitHandle); |
206 | cwh->proc = proc; | 213 | cwh->proc = proc; |
@@ -221,23 +228,20 @@ GNUNET_wait_child (struct GNUNET_OS_Process *proc, | |||
221 | return cwh; | 228 | return cwh; |
222 | } | 229 | } |
223 | 230 | ||
231 | |||
232 | /** | ||
233 | * Removing child handle. | ||
234 | * | ||
235 | * @param cwh The handle to be removed. | ||
236 | */ | ||
224 | void | 237 | void |
225 | GNUNET_wait_child_cancel (struct GNUNET_ChildWaitHandle *cwh) | 238 | GNUNET_wait_child_cancel (struct GNUNET_ChildWaitHandle *cwh) |
226 | { | 239 | { |
227 | if ((NULL != cwh_head)) | 240 | GNUNET_CONTAINER_DLL_remove (cwh_head, |
228 | { | 241 | cwh_tail, |
229 | GNUNET_CONTAINER_DLL_remove (cwh_head, | 242 | cwh); |
230 | cwh_tail, | ||
231 | cwh); | ||
232 | } | ||
233 | if (NULL == cwh_head) | ||
234 | { | ||
235 | child_management_done (); | ||
236 | } | ||
237 | if (NULL != sig_task) | ||
238 | { | ||
239 | GNUNET_SCHEDULER_cancel (sig_task); | ||
240 | sig_task = NULL; | ||
241 | } | ||
242 | GNUNET_free (cwh); | 243 | GNUNET_free (cwh); |
244 | if (NULL != cwh_head) | ||
245 | return; | ||
246 | child_management_done (); | ||
243 | } | 247 | } |