diff options
author | Andrew Stitcher <astitcher@apache.org> | 2009-03-02 18:42:02 +0000 |
---|---|---|
committer | Andrew Stitcher <astitcher@apache.org> | 2009-03-02 18:42:02 +0000 |
commit | ecd668842148df98b9e5bbea8fbc88a5f363d42b (patch) | |
tree | d818ee678418a18e94bf8ab25dc23ab907586d00 /cpp/src/tests/DispatcherTest.cpp | |
parent | 3578e8a032e35da6979edf48520a3b08a06f2e04 (diff) | |
download | qpid-python-ecd668842148df98b9e5bbea8fbc88a5f363d42b.tar.gz |
- Reworked DispatchHandler state machine to eliminate race conditions
particularly when deleting a DispatchHandle
- Reworked Poller interrupt mechanism eliminating locking problems and
to support DispatchHandler changes
- Beefed up the DispatchHandler test program so that it's a fair torture
test of the DispatchHandler code
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@749406 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/src/tests/DispatcherTest.cpp')
-rw-r--r-- | cpp/src/tests/DispatcherTest.cpp | 78 |
1 files changed, 67 insertions, 11 deletions
diff --git a/cpp/src/tests/DispatcherTest.cpp b/cpp/src/tests/DispatcherTest.cpp index c2f6bca12a..8fdc3b9aea 100644 --- a/cpp/src/tests/DispatcherTest.cpp +++ b/cpp/src/tests/DispatcherTest.cpp @@ -78,9 +78,6 @@ void reader(DispatchHandle& h, int fd) { h.rewatch(); } -DispatchHandle* rh = 0; -DispatchHandle* wh = 0; - void rInterrupt(DispatchHandle&) { cerr << "R"; } @@ -92,9 +89,28 @@ void wInterrupt(DispatchHandle&) { DispatchHandle::Callback rcb = rInterrupt; DispatchHandle::Callback wcb = wInterrupt; +DispatchHandleRef *volatile rh = 0; +DispatchHandleRef *volatile wh = 0; + +volatile bool stopWait = false; +volatile bool phase1finished = false; + +timer_t timer; + +void stop_handler(int /*signo*/, siginfo_t* /*info*/, void* /*context*/) { + stopWait = true; +} + void timer_handler(int /*signo*/, siginfo_t* /*info*/, void* /*context*/) { - rh->call(rcb); - wh->call(wcb); + static int count = 0; + if (count++ < 10) { + rh->call(rcb); + wh->call(wcb); + } else { + phase1finished = true; + int rc = ::timer_delete(timer); + assert(rc == 0); + } } int main(int /*argc*/, char** /*argv*/) @@ -132,8 +148,8 @@ int main(int /*argc*/, char** /*argv*/) PosixIOHandle f0(sv[0]); PosixIOHandle f1(sv[1]); - rh = new DispatchHandle(f0, boost::bind(reader, _1, sv[0]), 0, 0); - wh = new DispatchHandle(f1, 0, boost::bind(writer, _1, sv[1], testString), 0); + rh = new DispatchHandleRef(f0, boost::bind(reader, _1, sv[0]), 0, 0); + wh = new DispatchHandleRef(f1, 0, boost::bind(writer, _1, sv[1], testString), 0); rh->startWatch(poller); wh->startWatch(poller); @@ -154,11 +170,10 @@ int main(int /*argc*/, char** /*argv*/) rc = ::sigaction(SIGRTMIN, &sa,0); assert(rc == 0); - ::sigevent se; + ::sigevent se={}; se.sigev_notify = SIGEV_SIGNAL; se.sigev_signo = SIGRTMIN; se.sigev_value.sival_ptr = 0; - timer_t timer; rc = ::timer_create(CLOCK_REALTIME, &se, &timer); assert(rc == 0); @@ -169,11 +184,52 @@ int main(int /*argc*/, char** /*argv*/) rc = ::timer_settime(timer, 0, &ts, 0); assert(rc == 0); - // wait 2 minutes then shutdown - ::sleep(60); + // wait + while (!phase1finished) { + ::sleep(1); + } + + // Now test deleting/creating DispatchHandles in tight loop, so that we are likely to still be using the + // attached PollerHandles after deleting the DispatchHandle + DispatchHandleRef* t = wh; + wh = 0; + delete t; + t = rh; + rh = 0; + delete t; + + sa.sa_sigaction = stop_handler; + rc = ::sigaction(SIGRTMIN, &sa,0); + assert(rc == 0); + + itimerspec nts = { + /*.it_value = */ {30, 0}, // s, ns + /*.it_interval = */ {30, 0}}; // s, ns + + rc = ::timer_create(CLOCK_REALTIME, &se, &timer); + assert(rc == 0); + rc = ::timer_settime(timer, 0, &nts, 0); + assert(rc == 0); + + DispatchHandleRef* rh1; + DispatchHandleRef* wh1; + + struct timespec w = {0, 1000000}; + while (!stopWait) { + rh1 = new DispatchHandleRef(f0, boost::bind(reader, _1, sv[0]), 0, 0); + wh1 = new DispatchHandleRef(f1, 0, boost::bind(writer, _1, sv[1], testString), 0); + rh1->startWatch(poller); + wh1->startWatch(poller); + + ::nanosleep(&w, 0); + + delete wh1; + delete rh1; + } rc = ::timer_delete(timer); assert(rc == 0); + poller->shutdown(); dt.join(); dt1.join(); |