diff options
| author | Ted Ross <tross@apache.org> | 2013-04-29 19:48:59 +0000 |
|---|---|---|
| committer | Ted Ross <tross@apache.org> | 2013-04-29 19:48:59 +0000 |
| commit | 7cfe95015ef397b72a1f7c8d60a4e9023dcd6d5e (patch) | |
| tree | f0e0819ac11c83bf9f4a9d841a5141f93076693a | |
| parent | e0aad6d0b805d6dd8989a97c0232101bebaa155a (diff) | |
| download | qpid-python-7cfe95015ef397b72a1f7c8d60a4e9023dcd6d5e.tar.gz | |
QPID-4788 - Fixed linked-list corruption when an immediate timer is re-scheduled. Added test.
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@1477300 13f79535-47bb-0310-9956-ffa450edef68
| -rw-r--r-- | extras/dispatch/include/qpid/dispatch/ctools.h | 1 | ||||
| -rw-r--r-- | extras/dispatch/include/qpid/dispatch/timer.h | 2 | ||||
| -rw-r--r-- | extras/dispatch/src/timer.c | 1 | ||||
| -rw-r--r-- | extras/dispatch/tests/timer_test.c | 25 | ||||
| -rw-r--r-- | extras/dispatch/tests/tool_test.c | 41 |
5 files changed, 69 insertions, 1 deletions
diff --git a/extras/dispatch/include/qpid/dispatch/ctools.h b/extras/dispatch/include/qpid/dispatch/ctools.h index 33178a23ee..655c49f261 100644 --- a/extras/dispatch/include/qpid/dispatch/ctools.h +++ b/extras/dispatch/include/qpid/dispatch/ctools.h @@ -117,6 +117,7 @@ do { \ do { \ CT_ASSERT((i)->next == 0); \ CT_ASSERT((i)->prev == 0); \ + CT_ASSERT(a); \ if ((a)->next) \ (a)->next->prev = (i); \ else \ diff --git a/extras/dispatch/include/qpid/dispatch/timer.h b/extras/dispatch/include/qpid/dispatch/timer.h index 33b7d35dcd..4d22484896 100644 --- a/extras/dispatch/include/qpid/dispatch/timer.h +++ b/extras/dispatch/include/qpid/dispatch/timer.h @@ -69,7 +69,7 @@ void dx_timer_free(dx_timer_t *timer); * * @param timer Pointer to the timer object returned by dx_timer. * @param msec The minimum number of milliseconds of delay until the timer fires. - * If 0 is supplied, the timer will fire immediately. + * If 0 is supplied, the timer will be scheduled to fire immediately. */ void dx_timer_schedule(dx_timer_t *timer, long msec); diff --git a/extras/dispatch/src/timer.c b/extras/dispatch/src/timer.c index cb957e8400..0d5b301a6e 100644 --- a/extras/dispatch/src/timer.c +++ b/extras/dispatch/src/timer.c @@ -57,6 +57,7 @@ static void dx_timer_cancel_LH(dx_timer_t *timer) case TIMER_PENDING: dx_server_timer_cancel_LH(timer); + DEQ_INSERT_TAIL(idle_timers, timer); break; } diff --git a/extras/dispatch/tests/timer_test.c b/extras/dispatch/tests/timer_test.c index be20d2aabb..93725dde4b 100644 --- a/extras/dispatch/tests/timer_test.c +++ b/extras/dispatch/tests/timer_test.c @@ -94,6 +94,30 @@ static char* test_immediate(void *context) } +static char* test_immediate_reschedule(void *context) +{ + while(fire_head()); + fire_mask = 0; + + dx_timer_schedule(timers[0], 0); + dx_timer_schedule(timers[0], 0); + + if (fire_mask != 0) return "pass 1 - Premature firing"; + if (fire_head() > 1) return "pass 1 - Too many firings"; + if (fire_mask != 1) return "pass 1 - Incorrect fire mask"; + + fire_mask = 0; + dx_timer_schedule(timers[0], 0); + dx_timer_schedule(timers[0], 0); + + if (fire_mask != 0) return "pass 2 - Premature firing"; + if (fire_head() > 1) return "pass 2 - Too many firings"; + if (fire_mask != 1) return "pass 2 - Incorrect fire mask"; + + return 0; +} + + static char* test_immediate_plus_delayed(void *context) { while(fire_head()); @@ -369,6 +393,7 @@ int timer_tests(void) TEST_CASE(test_quiet, 0); TEST_CASE(test_immediate, 0); + TEST_CASE(test_immediate_reschedule, 0); TEST_CASE(test_immediate_plus_delayed, 0); TEST_CASE(test_single, 0); TEST_CASE(test_two_inorder, 0); diff --git a/extras/dispatch/tests/tool_test.c b/extras/dispatch/tests/tool_test.c index 7923ee3381..ba047d928c 100644 --- a/extras/dispatch/tests/tool_test.c +++ b/extras/dispatch/tests/tool_test.c @@ -148,11 +148,52 @@ static char* test_deq_basic(void *context) } +static char* test_deq_basic2(void *context) +{ + item_list_t list; + item_t item[10]; + item_t *ptr; + int idx; + char *subtest; + + DEQ_INIT(list); + if (DEQ_SIZE(list) != 0) return "Expected zero initial size"; + + for (idx = 0; idx < 10; idx++) { + DEQ_ITEM_INIT(&item[idx]); + item[idx].letter = '0' + idx; + } + + DEQ_INSERT_TAIL(list, &item[0]); + if (DEQ_SIZE(list) != 1) return "Expected 1 items in list"; + subtest = list_well_formed(list, "0"); + if (subtest) return subtest; + + ptr = DEQ_HEAD(list); + DEQ_REMOVE_HEAD(list); + if (ptr->letter != '0') return "Expected item '0'"; + if (DEQ_SIZE(list) != 0) return "Expected 0 items in list"; + + DEQ_INSERT_TAIL(list, &item[0]); + if (DEQ_SIZE(list) != 1) return "Expected 1 items in list"; + subtest = list_well_formed(list, "0"); + if (subtest) return subtest; + + ptr = DEQ_HEAD(list); + DEQ_REMOVE_HEAD(list); + if (ptr->letter != '0') return "Expected item '0'"; + if (DEQ_SIZE(list) != 0) return "Expected 0 items in list"; + + return 0; +} + + int tool_tests(void) { int result = 0; TEST_CASE(test_deq_basic, 0); + TEST_CASE(test_deq_basic2, 0); return result; } |
