This is an automated email from the ASF dual-hosted git repository. duke8253 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push: new 426fd28 fix race condition in test 426fd28 is described below commit 426fd28467463180925f069583fae91aa976e050 Author: Fei Deng <duke8...@gmail.com> AuthorDate: Tue Jul 2 14:35:05 2019 -0500 fix race condition in test --- tests/tools/plugins/cont_schedule.cc | 76 ++++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 29 deletions(-) diff --git a/tests/tools/plugins/cont_schedule.cc b/tests/tools/plugins/cont_schedule.cc index e678029..7a3b0c6 100644 --- a/tests/tools/plugins/cont_schedule.cc +++ b/tests/tools/plugins/cont_schedule.cc @@ -36,8 +36,8 @@ static char support_email[] = "duke8...@apache.org"; static int test_flag = 0; -static TSEventThread test_thread = nullptr; -static TSThread check_thread = nullptr; +static TSEventThread thread_1 = nullptr; +static TSEventThread thread_2 = nullptr; static int TSContSchedule_handler_1(TSCont contp, TSEvent event, void *edata); static int TSContSchedule_handler_2(TSCont contp, TSEvent event, void *edata); @@ -51,8 +51,9 @@ static int TSContSchedule_handler_1(TSCont contp, TSEvent event, void *edata) { TSDebug(DEBUG_TAG_HDL, "TSContSchedule handler 1 thread [%p]", TSThreadSelf()); - if (test_thread == nullptr) { - test_thread = TSEventThreadSelf(); + if (thread_1 == nullptr) { + // First time entering this handler, before everything else starts. + thread_1 = TSEventThreadSelf(); TSCont contp_new = TSContCreate(TSContSchedule_handler_2, TSMutexCreate()); @@ -60,15 +61,20 @@ TSContSchedule_handler_1(TSCont contp, TSEvent event, void *edata) TSDebug(DEBUG_TAG_HDL, "[%s] could not create continuation", plugin_name); abort(); } else { + // Set the affinity of contp_new to thread_1, and schedule it twice. TSDebug(DEBUG_TAG_HDL, "[%s] scheduling continuation", plugin_name); - TSContThreadAffinitySet(contp_new, test_thread); + TSContThreadAffinitySet(contp_new, thread_1); TSContSchedule(contp_new, 0); TSContSchedule(contp_new, 100); } - } else if (check_thread == nullptr) { + } else if (thread_2 == nullptr) { TSDebug(DEBUG_TAG_CHK, "fail [schedule delay not applied]"); } else { - if (check_thread != TSThreadSelf()) { + // Second time in here, should be after the two scheduled handler_2 runs. + // Since handler_1 has no affinity set, we should be on a different thread now. + // Also, thread_2 should be the same as thread_1, since thread_1 was set as + // affinity for handler_2. + if (thread_2 != TSEventThreadSelf() && thread_2 == thread_1) { TSDebug(DEBUG_TAG_CHK, "pass [should not be the same thread]"); } else { TSDebug(DEBUG_TAG_CHK, "fail [on the same thread]"); @@ -81,9 +87,13 @@ static int TSContSchedule_handler_2(TSCont contp, TSEvent event, void *edata) { TSDebug(DEBUG_TAG_HDL, "TSContSchedule handler 2 thread [%p]", TSThreadSelf()); - if (check_thread == nullptr) { - check_thread = TSThreadSelf(); - } else if (check_thread == TSThreadSelf()) { + if (thread_2 == nullptr) { + // First time in this handler, should get here after handler_1, + // and also record the thread id. + thread_2 = TSEventThreadSelf(); + } else if (thread_2 == TSEventThreadSelf()) { + // Second time in here, since the affinity is set to thread_1, we should be + // on the same thread as last time. TSDebug(DEBUG_TAG_CHK, "pass [should be the same thread]"); } else { TSDebug(DEBUG_TAG_CHK, "fail [not the same thread]"); @@ -94,16 +104,18 @@ TSContSchedule_handler_2(TSCont contp, TSEvent event, void *edata) static int TSContScheduleOnPool_handler_1(TSCont contp, TSEvent event, void *edata) { + // This runs on ET_NET threads. TSDebug(DEBUG_TAG_HDL, "TSContScheduleOnPool handler 1 thread [%p]", TSThreadSelf()); - if (check_thread == nullptr) { - check_thread = TSThreadSelf(); + if (thread_1 == nullptr) { + // First time here, record thread id. + thread_1 = TSEventThreadSelf(); } else { - if (check_thread != TSThreadSelf()) { + // Second time here, we should be on a different thread since affinity was cleared. + if (thread_1 != TSEventThreadSelf()) { TSDebug(DEBUG_TAG_CHK, "pass [should not be the same thread]"); } else { TSDebug(DEBUG_TAG_CHK, "fail [on the same thread]"); } - check_thread = nullptr; } return 0; } @@ -111,16 +123,20 @@ TSContScheduleOnPool_handler_1(TSCont contp, TSEvent event, void *edata) static int TSContScheduleOnPool_handler_2(TSCont contp, TSEvent event, void *edata) { + // This runs on ET_TASK threads. TSDebug(DEBUG_TAG_HDL, "TSContScheduleOnPool handler 2 thread [%p]", TSThreadSelf()); - if (check_thread == nullptr) { - check_thread = TSThreadSelf(); + if (thread_2 == nullptr) { + // First time here, record thread id. + thread_2 = TSEventThreadSelf(); } else { - if (check_thread == TSThreadSelf()) { + if (thread_2 == TSEventThreadSelf()) { + // Second time there, we should be on the same thread even though affinity was cleared, + // reason being plugin is running on ET_TASK threads, and we were scheduled on ET_TASK + // threads as well, so the thread the plugin is on is used and set to affinity. TSDebug(DEBUG_TAG_CHK, "pass [should be the same thread]"); } else { TSDebug(DEBUG_TAG_CHK, "fail [not the same thread]"); } - check_thread = TSThreadSelf(); } return 0; } @@ -128,9 +144,11 @@ TSContScheduleOnPool_handler_2(TSCont contp, TSEvent event, void *edata) static int TSContScheduleOnThread_handler_1(TSCont contp, TSEvent event, void *edata) { + // Mostly same as TSContSchedule_handler_1, no need to set affinity + // since we are scheduling directly on to a thread. TSDebug(DEBUG_TAG_HDL, "TSContScheduleOnThread handler 1 thread [%p]", TSThreadSelf()); - if (test_thread == nullptr) { - test_thread = TSEventThreadSelf(); + if (thread_1 == nullptr) { + thread_1 = TSEventThreadSelf(); TSCont contp_new = TSContCreate(TSContScheduleOnThread_handler_2, TSMutexCreate()); @@ -139,13 +157,13 @@ TSContScheduleOnThread_handler_1(TSCont contp, TSEvent event, void *edata) abort(); } else { TSDebug(DEBUG_TAG_HDL, "[%s] scheduling continuation", plugin_name); - TSContScheduleOnThread(contp_new, 0, test_thread); - TSContScheduleOnThread(contp_new, 100, test_thread); + TSContScheduleOnThread(contp_new, 0, thread_1); + TSContScheduleOnThread(contp_new, 100, thread_1); } - } else if (check_thread == nullptr) { + } else if (thread_2 == nullptr) { TSDebug(DEBUG_TAG_CHK, "fail [schedule delay not applied]"); } else { - if (check_thread != TSThreadSelf()) { + if (thread_2 != TSEventThreadSelf()) { TSDebug(DEBUG_TAG_CHK, "pass [should not be the same thread]"); } else { TSDebug(DEBUG_TAG_CHK, "fail [on the same thread]"); @@ -158,9 +176,9 @@ static int TSContScheduleOnThread_handler_2(TSCont contp, TSEvent event, void *edata) { TSDebug(DEBUG_TAG_HDL, "TSContScheduleOnThread handler 2 thread [%p]", TSThreadSelf()); - if (check_thread == nullptr) { - check_thread = TSThreadSelf(); - } else if (check_thread == TSThreadSelf()) { + if (thread_2 == nullptr) { + thread_2 = TSEventThreadSelf(); + } else if (thread_2 == TSEventThreadSelf()) { TSDebug(DEBUG_TAG_CHK, "pass [should be the same thread]"); } else { TSDebug(DEBUG_TAG_CHK, "fail [not the same thread]"); @@ -173,7 +191,7 @@ TSContThreadAffinity_handler(TSCont contp, TSEvent event, void *edata) { TSDebug(DEBUG_TAG_HDL, "TSContThreadAffinity handler thread [%p]", TSThreadSelf()); - test_thread = TSEventThreadSelf(); + thread_1 = TSEventThreadSelf(); if (TSContThreadAffinityGet(contp) != nullptr) { TSDebug(DEBUG_TAG_CHK, "pass [affinity thread is not null]"); @@ -181,7 +199,7 @@ TSContThreadAffinity_handler(TSCont contp, TSEvent event, void *edata) if (TSContThreadAffinityGet(contp) == nullptr) { TSDebug(DEBUG_TAG_CHK, "pass [affinity thread is cleared]"); TSContThreadAffinitySet(contp, TSEventThreadSelf()); - if (TSContThreadAffinityGet(contp) == test_thread) { + if (TSContThreadAffinityGet(contp) == thread_1) { TSDebug(DEBUG_TAG_CHK, "pass [affinity thread is set]"); } else { TSDebug(DEBUG_TAG_CHK, "fail [affinity thread is not set]");