summaryrefslogtreecommitdiff
path: root/cpp/src/tests/DispatcherTest.cpp
diff options
context:
space:
mode:
authorAndrew Stitcher <astitcher@apache.org>2009-03-02 18:42:02 +0000
committerAndrew Stitcher <astitcher@apache.org>2009-03-02 18:42:02 +0000
commitecd668842148df98b9e5bbea8fbc88a5f363d42b (patch)
treed818ee678418a18e94bf8ab25dc23ab907586d00 /cpp/src/tests/DispatcherTest.cpp
parent3578e8a032e35da6979edf48520a3b08a06f2e04 (diff)
downloadqpid-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.cpp78
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();