summaryrefslogtreecommitdiff
path: root/testnet/TestEthernetTap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'testnet/TestEthernetTap.cpp')
-rw-r--r--testnet/TestEthernetTap.cpp32
1 files changed, 17 insertions, 15 deletions
diff --git a/testnet/TestEthernetTap.cpp b/testnet/TestEthernetTap.cpp
index fd594a21..3d29d6e2 100644
--- a/testnet/TestEthernetTap.cpp
+++ b/testnet/TestEthernetTap.cpp
@@ -80,9 +80,9 @@ TestEthernetTap::~TestEthernetTap()
static const TestFrame zf;
{
Mutex::Lock _l(_pq_m);
- _pq.push(zf); // 0 length frame = exit
+ _pq.push_back(zf); // 0 length frame = exit
+ _pq_c.signal();
}
- _pq_c.signal();
Thread::join(_thread);
}
@@ -138,9 +138,9 @@ bool TestEthernetTap::injectPacketFromHost(const MAC &from,const MAC &to,unsigne
{
Mutex::Lock _l(_pq_m);
- _pq.push(TestFrame(from,to,data,etherType & 0xffff,len));
+ _pq.push_back(TestFrame(from,to,data,etherType & 0xffff,len));
+ _pq_c.signal();
}
- _pq_c.signal();
return true;
}
@@ -148,23 +148,25 @@ bool TestEthernetTap::injectPacketFromHost(const MAC &from,const MAC &to,unsigne
void TestEthernetTap::threadMain()
throw()
{
- TestFrame tf;
+ std::vector<TestFrame> q;
for(;;) {
- tf.len = 0;
{
Mutex::Lock _l(_pq_m);
- if (!_pq.empty()) {
- if (_pq.front().len == 0)
- break;
- memcpy(&tf,&(_pq.front()),sizeof(tf));
- _pq.pop();
- }
+ q = _pq;
+ _pq.clear();
}
- if ((tf.len > 0)&&(_enabled))
- _handler(_arg,tf.from,tf.to,tf.etherType,Buffer<4096>(tf.data,tf.len));
+ for(std::vector<TestFrame>::iterator f(q.begin());f!=q.end();++f) {
+ if (!f->len)
+ return; // empty frame signals thread to die
+ else if (_enabled) {
+ try {
+ _handler(_arg,f->from,f->to,f->etherType,Buffer<4096>(f->data,f->len));
+ } catch ( ... ) {} // handlers should not throw
+ }
+ }
- _pq_c.wait();
+ _pq_c.wait(1000);
}
}