1 /*
2 * Copyright 2008-2014 Arsen Chaloyan
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * $Id: apt_task.c 2219 2014-11-11 02:35:14Z achaloyan@gmail.com $
17 */
18
19 #ifdef WIN32
20 #pragma warning(disable: 4127)
21 #endif
22 #include <apr_ring.h>
23 #include <apr_thread_proc.h>
24 #include <apr_thread_cond.h>
25 #include <apr_portable.h>
26 #include "apt_task.h"
27 #include "apt_log.h"
28
29 /** Internal states of the task */
30 typedef enum {
31 TASK_STATE_IDLE, /**< no task activity */
32 TASK_STATE_START_REQUESTED, /**< start of the task has been requested, but it's not running yet */
33 TASK_STATE_RUNNING, /**< task is running */
34 TASK_STATE_TERMINATE_REQUESTED /**< termination of the task has been requested, but it's still running */
35 } apt_task_state_e;
36
37 struct apt_task_t {
38 APR_RING_ENTRY(apt_task_t) link; /* entry to parent task ring */
39 APR_RING_HEAD(apt_task_head_t, apt_task_t) head; /* head of child tasks ring */
40
41 const char *name; /* name of the task */
42 void *obj; /* external object associated with the task */
43 apr_pool_t *pool; /* memory pool to allocate task data from */
44 apt_task_msg_pool_t *msg_pool; /* message pool to allocate task messages from */
45 apr_thread_mutex_t *data_guard; /* mutex to protect task data */
46 apr_thread_t *thread_handle; /* thread handle */
47 apt_task_state_e state; /* current task state */
48 apt_task_vtable_t vtable; /* table of virtual methods */
49 apt_task_t *parent_task; /* parent (master) task */
50 apr_size_t pending_start; /* number of pending start requests */
51 apr_size_t pending_term; /* number of pending terminate requests */
52 apr_size_t pending_off; /* number of pending taking-offline requests */
53 apr_size_t pending_on; /* number of pending bringing-online requests */
54 apt_bool_t running; /* task is running (TRUE if even terminate has already been requested) */
55 apt_bool_t auto_ready; /* if TRUE, task is implicitly ready to process messages */
56 };
57
58 static void* APR_THREAD_FUNC apt_task_run(apr_thread_t *thread_handle, void *data);
59 static APR_INLINE void apt_task_vtable_reset(apt_task_vtable_t *vtable);
60
61 static apt_bool_t apt_task_core_msg_signal(apt_task_t *task, apt_task_msg_pool_t *msg_pool, apt_core_task_msg_type_e type);
62
63 static apt_bool_t apt_task_terminate_request(apt_task_t *task);
64
65 static apt_bool_t apt_task_start_process_internal(apt_task_t *task);
66 static apt_bool_t apt_task_terminate_process_internal(apt_task_t *task);
67 static apt_bool_t apt_task_offline_request_process(apt_task_t *task);
68 static apt_bool_t apt_task_online_request_process(apt_task_t *task);
69
70 static apt_bool_t apt_task_offline_request_complete(apt_task_t *task);
71 static apt_bool_t apt_task_online_request_complete(apt_task_t *task);
72
73 static void apt_task_start_complete_raise(apt_task_t *task);
74 static void apt_task_terminate_complete_raise(apt_task_t *task);
75 static void apt_task_offline_complete_raise(apt_task_t *task);
76 static void apt_task_online_complete_raise(apt_task_t *task);
77
78
apt_task_create(void * obj,apt_task_msg_pool_t * msg_pool,apr_pool_t * pool)79 APT_DECLARE(apt_task_t*) apt_task_create(
80 void *obj,
81 apt_task_msg_pool_t *msg_pool,
82 apr_pool_t *pool)
83 {
84 apt_task_t *task = apr_palloc(pool,sizeof(apt_task_t));
85 task->obj = obj;
86 task->pool = pool;
87 task->msg_pool = msg_pool;
88
89 if(!task->msg_pool) {
90 task->msg_pool = apt_task_msg_pool_create_dynamic(0,pool);
91 }
92
93 task->state = TASK_STATE_IDLE;
94 task->thread_handle = NULL;
95 if(apr_thread_mutex_create(&task->data_guard, APR_THREAD_MUTEX_DEFAULT, task->pool) != APR_SUCCESS) {
96 return NULL;
97 }
98
99 /* reset vtable */
100 apt_task_vtable_reset(&task->vtable);
101 task->vtable.terminate = apt_task_terminate_request;
102 task->vtable.process_start = apt_task_start_process_internal;
103 task->vtable.process_terminate = apt_task_terminate_process_internal;
104
105 APR_RING_ELEM_INIT(task, link);
106 APR_RING_INIT(&task->head, apt_task_t, link);
107
108 task->parent_task = NULL;
109 task->pending_start = 0;
110 task->pending_term = 0;
111 task->pending_off = 0;
112 task->pending_on = 0;
113 task->auto_ready = TRUE;
114 task->name = "Task";
115 return task;
116 }
117
apt_task_destroy(apt_task_t * task)118 APT_DECLARE(apt_bool_t) apt_task_destroy(apt_task_t *task)
119 {
120 apt_task_t *child_task;
121 APR_RING_FOREACH(child_task, &task->head, apt_task_t, link) {
122 apt_task_destroy(child_task);
123 }
124
125 if(task->state != TASK_STATE_IDLE) {
126 apt_task_wait_till_complete(task);
127 }
128
129 apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Destroy Task [%s]",task->name);
130 if(task->vtable.destroy) {
131 task->vtable.destroy(task);
132 }
133
134 apr_thread_mutex_destroy(task->data_guard);
135 return TRUE;
136 }
137
apt_task_add(apt_task_t * task,apt_task_t * child_task)138 APT_DECLARE(apt_bool_t) apt_task_add(apt_task_t *task, apt_task_t *child_task)
139 {
140 if(!child_task)
141 return FALSE;
142
143 child_task->parent_task = task;
144 APR_RING_INSERT_TAIL(&task->head,child_task,apt_task_t,link);
145 return TRUE;
146 }
147
apt_task_start(apt_task_t * task)148 APT_DECLARE(apt_bool_t) apt_task_start(apt_task_t *task)
149 {
150 apt_bool_t status = TRUE;
151 apr_thread_mutex_lock(task->data_guard);
152 if(task->state == TASK_STATE_IDLE) {
153 apr_status_t rv;
154 task->state = TASK_STATE_START_REQUESTED;
155 apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Start Task [%s]",task->name);
156 if(task->vtable.start) {
157 /* invoke virtual start method */
158 task->vtable.start(task);
159 }
160 else {
161 /* start new thread by default */
162 rv = apr_thread_create(&task->thread_handle,NULL,apt_task_run,task,task->pool);
163 if(rv != APR_SUCCESS) {
164 task->state = TASK_STATE_IDLE;
165 status = FALSE;
166 }
167 }
168 }
169 else {
170 status = FALSE;
171 }
172 apr_thread_mutex_unlock(task->data_guard);
173 return status;
174 }
175
apt_task_offline(apt_task_t * task)176 APT_DECLARE(apt_bool_t) apt_task_offline(apt_task_t *task)
177 {
178 return apt_task_core_msg_signal(task,task->msg_pool,CORE_TASK_MSG_TAKEOFFLINE_REQUEST);
179 }
180
apt_task_online(apt_task_t * task)181 APT_DECLARE(apt_bool_t) apt_task_online(apt_task_t *task)
182 {
183 return apt_task_core_msg_signal(task,task->msg_pool,CORE_TASK_MSG_BRINGONLINE_REQUEST);
184 }
185
apt_task_terminate(apt_task_t * task,apt_bool_t wait_till_complete)186 APT_DECLARE(apt_bool_t) apt_task_terminate(apt_task_t *task, apt_bool_t wait_till_complete)
187 {
188 apt_bool_t status = FALSE;
189 apr_thread_mutex_lock(task->data_guard);
190 if(task->state == TASK_STATE_START_REQUESTED || task->state == TASK_STATE_RUNNING) {
191 task->state = TASK_STATE_TERMINATE_REQUESTED;
192 }
193 apr_thread_mutex_unlock(task->data_guard);
194
195 if(task->state == TASK_STATE_TERMINATE_REQUESTED) {
196 /* invoke virtual terminate method */
197 apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Terminate Task [%s]",task->name);
198 if(task->vtable.terminate) {
199 status = task->vtable.terminate(task);
200 }
201
202 if(wait_till_complete == TRUE && status == TRUE) {
203 apt_task_wait_till_complete(task);
204 }
205 }
206
207 return status;
208 }
209
apt_task_wait_till_complete(apt_task_t * task)210 APT_DECLARE(apt_bool_t) apt_task_wait_till_complete(apt_task_t *task)
211 {
212 if(task->thread_handle) {
213 apr_status_t s;
214 apr_thread_join(&s,task->thread_handle);
215 task->thread_handle = NULL;
216 }
217 return TRUE;
218 }
219
apt_task_delay(apr_size_t msec)220 APT_DECLARE(void) apt_task_delay(apr_size_t msec)
221 {
222 apr_sleep(1000*msec);
223 }
224
apt_task_parent_get(const apt_task_t * task)225 APT_DECLARE(apt_task_t*) apt_task_parent_get(const apt_task_t *task)
226 {
227 return task->parent_task;
228 }
229
apt_task_pool_get(const apt_task_t * task)230 APT_DECLARE(apr_pool_t*) apt_task_pool_get(const apt_task_t *task)
231 {
232 return task->pool;
233 }
234
apt_task_object_get(const apt_task_t * task)235 APT_DECLARE(void*) apt_task_object_get(const apt_task_t *task)
236 {
237 return task->obj;
238 }
239
apt_task_vtable_get(apt_task_t * task)240 APT_DECLARE(apt_task_vtable_t*) apt_task_vtable_get(apt_task_t *task)
241 {
242 return &task->vtable;
243 }
244
apt_task_name_set(apt_task_t * task,const char * name)245 APT_DECLARE(void) apt_task_name_set(apt_task_t *task, const char *name)
246 {
247 task->name = name;
248 }
249
apt_task_name_get(const apt_task_t * task)250 APT_DECLARE(const char*) apt_task_name_get(const apt_task_t *task)
251 {
252 return task->name;
253 }
254
apt_task_msg_get(apt_task_t * task)255 APT_DECLARE(apt_task_msg_t*) apt_task_msg_get(apt_task_t *task)
256 {
257 if(task->msg_pool) {
258 return apt_task_msg_acquire(task->msg_pool);
259 }
260 return NULL;
261 }
262
apt_task_msg_signal(apt_task_t * task,apt_task_msg_t * msg)263 APT_DECLARE(apt_bool_t) apt_task_msg_signal(apt_task_t *task, apt_task_msg_t *msg)
264 {
265 apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Signal Message to [%s] ["APT_PTR_FMT";%d;%d]",
266 task->name, msg, msg->type, msg->sub_type);
267 if(task->vtable.signal_msg) {
268 if(task->vtable.signal_msg(task,msg) == TRUE) {
269 return TRUE;
270 }
271 }
272
273 apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Signal Task Message [%s] [0x%x;%d;%d]",
274 task->name, msg, msg->type, msg->sub_type);
275 apt_task_msg_release(msg);
276 return FALSE;
277 }
278
apt_task_msg_parent_signal(apt_task_t * task,apt_task_msg_t * msg)279 APT_DECLARE(apt_bool_t) apt_task_msg_parent_signal(apt_task_t *task, apt_task_msg_t *msg)
280 {
281 apt_task_t *parent_task = task->parent_task;
282 if(parent_task) {
283 return apt_task_msg_signal(parent_task,msg);
284 }
285
286 apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Null Parent Task [%s]",task->name);
287 apt_task_msg_release(msg);
288 return FALSE;
289 }
290
apt_task_core_msg_signal(apt_task_t * task,apt_task_msg_pool_t * msg_pool,apt_core_task_msg_type_e type)291 static apt_bool_t apt_task_core_msg_signal(apt_task_t *task, apt_task_msg_pool_t *msg_pool, apt_core_task_msg_type_e type)
292 {
293 if(task && msg_pool) {
294 apt_task_msg_t *msg = apt_task_msg_acquire(msg_pool);
295 /* signal core task message */
296 msg->type = TASK_MSG_CORE;
297 msg->sub_type = type;
298 return apt_task_msg_signal(task,msg);
299 }
300 return FALSE;
301 }
302
apt_core_task_msg_process(apt_task_t * task,apt_task_msg_t * msg)303 static apt_bool_t apt_core_task_msg_process(apt_task_t *task, apt_task_msg_t *msg)
304 {
305 switch(msg->sub_type) {
306 case CORE_TASK_MSG_START_COMPLETE:
307 apt_task_start_request_remove(task);
308 break;
309 case CORE_TASK_MSG_TERMINATE_REQUEST:
310 if(task->vtable.process_terminate) {
311 task->vtable.process_terminate(task);
312 }
313 break;
314 case CORE_TASK_MSG_TERMINATE_COMPLETE:
315 apt_task_terminate_request_remove(task);
316 break;
317 case CORE_TASK_MSG_TAKEOFFLINE_REQUEST:
318 apt_task_offline_request_process(task);
319 break;
320 case CORE_TASK_MSG_TAKEOFFLINE_COMPLETE:
321 apt_task_offline_request_complete(task);
322 break;
323 case CORE_TASK_MSG_BRINGONLINE_REQUEST:
324 apt_task_online_request_process(task);
325 break;
326 case CORE_TASK_MSG_BRINGONLINE_COMPLETE:
327 apt_task_online_request_complete(task);
328 break;
329 default: break;
330 }
331 return TRUE;
332 }
333
apt_task_msg_process(apt_task_t * task,apt_task_msg_t * msg)334 APT_DECLARE(apt_bool_t) apt_task_msg_process(apt_task_t *task, apt_task_msg_t *msg)
335 {
336 apt_bool_t status = FALSE;
337 apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Process Message [%s] ["APT_PTR_FMT";%d;%d]",
338 task->name, msg, msg->type, msg->sub_type);
339 if(msg->type == TASK_MSG_CORE) {
340 status = apt_core_task_msg_process(task,msg);
341 }
342 else {
343 if(task->vtable.process_msg) {
344 status = task->vtable.process_msg(task,msg);
345 }
346 }
347
348 apt_task_msg_release(msg);
349 return status;
350 }
351
apt_task_terminate_request(apt_task_t * task)352 static apt_bool_t apt_task_terminate_request(apt_task_t *task)
353 {
354 return apt_task_core_msg_signal(task,task->msg_pool,CORE_TASK_MSG_TERMINATE_REQUEST);
355 }
356
apt_task_start_request_process(apt_task_t * task)357 APT_DECLARE(apt_bool_t) apt_task_start_request_process(apt_task_t *task)
358 {
359 return apt_task_start_process_internal(task);
360 }
361
apt_task_start_process_internal(apt_task_t * task)362 static apt_bool_t apt_task_start_process_internal(apt_task_t *task)
363 {
364 apt_task_t *child_task;
365 APR_RING_FOREACH(child_task, &task->head, apt_task_t, link) {
366 if(apt_task_start(child_task) == TRUE) {
367 task->pending_start++;
368 }
369 }
370
371 if(!task->pending_start) {
372 /* no child task to start, just raise start-complete event */
373 apt_task_start_complete_raise(task);
374 }
375 return TRUE;
376 }
377
apt_task_terminate_request_process(apt_task_t * task)378 APT_DECLARE(apt_bool_t) apt_task_terminate_request_process(apt_task_t *task)
379 {
380 return apt_task_terminate_process_internal(task);
381 }
382
apt_task_terminate_process_internal(apt_task_t * task)383 static apt_bool_t apt_task_terminate_process_internal(apt_task_t *task)
384 {
385 apt_task_t *child_task;
386 APR_RING_FOREACH(child_task, &task->head, apt_task_t, link) {
387 #ifdef ENABLE_SIMULT_TASK_TERMINATION
388 if(child_task->thread_handle) {
389 apr_thread_detach(child_task->thread_handle);
390 child_task->thread_handle = NULL;
391 }
392 if(apt_task_terminate(child_task,FALSE) == TRUE) {
393 task->pending_term++;
394 }
395 #else
396 apt_task_terminate(child_task,TRUE);
397 #endif
398 }
399
400 if(!task->pending_term) {
401 /* no child task to terminate, just raise terminate-complete event */
402 apt_task_terminate_complete_raise(task);
403 task->running = FALSE;
404 }
405 return TRUE;
406 }
407
apt_task_offline_request_process(apt_task_t * task)408 static apt_bool_t apt_task_offline_request_process(apt_task_t *task)
409 {
410 apt_task_t *child_task;
411 APR_RING_FOREACH(child_task, &task->head, apt_task_t, link) {
412 if(apt_task_offline(child_task) == TRUE) {
413 task->pending_off++;
414 }
415 }
416
417 if(!task->pending_off) {
418 /* no child task, just raise offline-complete event */
419 apt_task_offline_complete_raise(task);
420 }
421 return TRUE;
422 }
423
apt_task_online_request_process(apt_task_t * task)424 static apt_bool_t apt_task_online_request_process(apt_task_t *task)
425 {
426 apt_task_t *child_task;
427 APR_RING_FOREACH(child_task, &task->head, apt_task_t, link) {
428 if(apt_task_online(child_task) == TRUE) {
429 task->pending_on++;
430 }
431 }
432
433 if(!task->pending_on) {
434 /* no child task, just raise online-complete event */
435 apt_task_online_complete_raise(task);
436 }
437 return TRUE;
438 }
439
apt_task_auto_ready_set(apt_task_t * task,apt_bool_t auto_ready)440 APT_DECLARE(void) apt_task_auto_ready_set(apt_task_t *task, apt_bool_t auto_ready)
441 {
442 task->auto_ready = auto_ready;
443 }
444
apt_task_ready(apt_task_t * task)445 APT_DECLARE(apt_bool_t) apt_task_ready(apt_task_t *task)
446 {
447 if(task->auto_ready == TRUE) {
448 return FALSE;
449 }
450
451 /* start child tasks (if any) */
452 if(task->vtable.process_start) {
453 task->vtable.process_start(task);
454 }
455 return TRUE;
456 }
457
apt_task_running_flag_get(apt_task_t * task)458 APT_DECLARE(apt_bool_t*) apt_task_running_flag_get(apt_task_t *task)
459 {
460 return &task->running;
461 }
462
apt_task_start_request_add(apt_task_t * task)463 APT_DECLARE(apt_bool_t) apt_task_start_request_add(apt_task_t *task)
464 {
465 task->pending_start++;
466 return TRUE;
467 }
468
apt_task_start_request_remove(apt_task_t * task)469 APT_DECLARE(apt_bool_t) apt_task_start_request_remove(apt_task_t *task)
470 {
471 if(!task->pending_start) {
472 /* error case, no pending start */
473 return FALSE;
474 }
475 task->pending_start--;
476 if(!task->pending_start) {
477 apt_task_start_complete_raise(task);
478 }
479 return TRUE;
480 }
481
apt_task_terminate_request_add(apt_task_t * task)482 APT_DECLARE(apt_bool_t) apt_task_terminate_request_add(apt_task_t *task)
483 {
484 task->pending_term++;
485 return TRUE;
486 }
487
apt_task_terminate_request_remove(apt_task_t * task)488 APT_DECLARE(apt_bool_t) apt_task_terminate_request_remove(apt_task_t *task)
489 {
490 if(!task->pending_term) {
491 /* error case, no pending terminate */
492 return FALSE;
493 }
494 task->pending_term--;
495 if(!task->pending_term) {
496 apt_task_terminate_complete_raise(task);
497 task->running = FALSE;
498 }
499 return TRUE;
500 }
501
apt_task_offline_request_complete(apt_task_t * task)502 static apt_bool_t apt_task_offline_request_complete(apt_task_t *task)
503 {
504 if(!task->pending_off) {
505 /* error case, no pending request */
506 return FALSE;
507 }
508 task->pending_off--;
509 if(!task->pending_off) {
510 apt_task_offline_complete_raise(task);
511 }
512 return TRUE;
513 }
514
apt_task_online_request_complete(apt_task_t * task)515 static apt_bool_t apt_task_online_request_complete(apt_task_t *task)
516 {
517 if(!task->pending_on) {
518 /* error case, no pending request */
519 return FALSE;
520 }
521 task->pending_on--;
522 if(!task->pending_on) {
523 apt_task_online_complete_raise(task);
524 }
525 return TRUE;
526 }
527
apt_task_start_complete_raise(apt_task_t * task)528 static void apt_task_start_complete_raise(apt_task_t *task)
529 {
530 apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Task Started [%s]",task->name);
531 if(task->vtable.on_start_complete) {
532 task->vtable.on_start_complete(task);
533 }
534 apt_task_core_msg_signal(task->parent_task,task->msg_pool,CORE_TASK_MSG_START_COMPLETE);
535 }
536
apt_task_terminate_complete_raise(apt_task_t * task)537 static void apt_task_terminate_complete_raise(apt_task_t *task)
538 {
539 apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Task Terminated [%s]",task->name);
540 if(task->vtable.on_terminate_complete) {
541 task->vtable.on_terminate_complete(task);
542 }
543 #ifdef ENABLE_SIMULT_TASK_TERMINATION
544 apt_task_core_msg_signal(task->parent_task,task->msg_pool,CORE_TASK_MSG_TERMINATE_COMPLETE);
545 #endif
546 }
547
apt_task_offline_complete_raise(apt_task_t * task)548 static void apt_task_offline_complete_raise(apt_task_t *task)
549 {
550 apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Task Taken Offline [%s]",task->name);
551 if(task->vtable.on_offline_complete) {
552 task->vtable.on_offline_complete(task);
553 }
554 apt_task_core_msg_signal(task->parent_task,task->msg_pool,CORE_TASK_MSG_TAKEOFFLINE_COMPLETE);
555 }
556
apt_task_online_complete_raise(apt_task_t * task)557 static void apt_task_online_complete_raise(apt_task_t *task)
558 {
559 apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Task Brought Online [%s]",task->name);
560 if(task->vtable.on_online_complete) {
561 task->vtable.on_online_complete(task);
562 }
563 apt_task_core_msg_signal(task->parent_task,task->msg_pool,CORE_TASK_MSG_BRINGONLINE_COMPLETE);
564 }
565
apt_task_run(apr_thread_t * thread_handle,void * data)566 static void* APR_THREAD_FUNC apt_task_run(apr_thread_t *thread_handle, void *data)
567 {
568 apt_task_t *task = data;
569
570 #if APR_HAS_SETTHREADNAME
571 apr_thread_name_set(task->name);
572 #endif
573 /* raise pre-run event */
574 if(task->vtable.on_pre_run) {
575 task->vtable.on_pre_run(task);
576 }
577 apr_thread_mutex_lock(task->data_guard);
578 task->state = TASK_STATE_RUNNING;
579 task->running = TRUE;
580 apr_thread_mutex_unlock(task->data_guard);
581
582 if(task->auto_ready == TRUE) {
583 /* start child tasks (if any) */
584 if(task->vtable.process_start) {
585 task->vtable.process_start(task);
586 }
587 }
588
589 /* run task */
590 if(task->vtable.run) {
591 task->vtable.run(task);
592 }
593
594 apr_thread_mutex_lock(task->data_guard);
595 task->state = TASK_STATE_IDLE;
596 task->running = FALSE;
597 apr_thread_mutex_unlock(task->data_guard);
598 /* raise post-run event */
599 if(task->vtable.on_post_run) {
600 task->vtable.on_post_run(task);
601 }
602
603 apr_thread_exit(thread_handle,APR_SUCCESS);
604 return NULL;
605 }
606
apt_task_vtable_reset(apt_task_vtable_t * vtable)607 static APR_INLINE void apt_task_vtable_reset(apt_task_vtable_t *vtable)
608 {
609 vtable->destroy = NULL;
610 vtable->start = NULL;
611 vtable->terminate = NULL;
612 vtable->run = NULL;
613 vtable->signal_msg = NULL;
614 vtable->process_msg = NULL;
615 vtable->process_start = NULL;
616 vtable->process_terminate = NULL;
617 vtable->on_pre_run = NULL;
618 vtable->on_post_run = NULL;
619 vtable->on_start_complete = NULL;
620 vtable->on_terminate_complete = NULL;
621 vtable->on_offline_complete = NULL;
622 vtable->on_online_complete = NULL;
623 }
624