Files
pvAccess/testApp/utils/namedLockPatternTest.cpp
2011-09-19 14:51:35 +01:00

228 lines
6.8 KiB
C++

/*
* namedLockPatternTest.cpp
*
*/
#include <pv/namedLockPattern.h>
#include <pv/inetAddressUtil.h>
#include <pv/status.h>
#include <pv/CDRMonitor.h>
#include <epicsAssert.h>
#include <epicsExit.h>
#include <epicsThread.h>
#include <epicsMessageQueue.h>
#include <osiSock.h>
#include <iostream>
#include <string.h>
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
epicsMessageQueueId join1;
epicsMessageQueueId join2;
void testIntLockPattern()
{
int64 timeout = 100;
NamedLockPattern<int> namedLockPattern;
int name1 = 1;
assert(namedLockPattern.acquireSynchronizationObject(name1,timeout));
assert(namedLockPattern.acquireSynchronizationObject(name1,timeout));
namedLockPattern.releaseSynchronizationObject(name1);
namedLockPattern.releaseSynchronizationObject(name1);
int name2 = 2;
assert(namedLockPattern.acquireSynchronizationObject(name2,timeout));
namedLockPattern.releaseSynchronizationObject(name2);
}
void testIntPtrLockPattern()
{
int64 timeout = 100;
NamedLockPattern<int*> namedLockPattern;
int name1 = 1;
assert(namedLockPattern.acquireSynchronizationObject(&name1,timeout));
assert(namedLockPattern.acquireSynchronizationObject(&name1,timeout));
namedLockPattern.releaseSynchronizationObject(&name1);
namedLockPattern.releaseSynchronizationObject(&name1);
int name2 = 2;
assert(namedLockPattern.acquireSynchronizationObject(&name2,timeout));
namedLockPattern.releaseSynchronizationObject(&name2);
}
struct cmp_str
{
bool operator()(char const *a, char const *b)
{
return strcmp(a, b) < 0;
}
};
void testCharPtrLockPattern()
{
int64 timeout = 100;
NamedLockPattern<const char*,cmp_str> namedLockPattern;
string name1 = "lojze";
assert(namedLockPattern.acquireSynchronizationObject(name1.c_str(),timeout));
assert(namedLockPattern.acquireSynchronizationObject(name1.c_str(),timeout));
namedLockPattern.releaseSynchronizationObject(name1.c_str());
namedLockPattern.releaseSynchronizationObject(name1.c_str());
string name2 = "francka";
assert(namedLockPattern.acquireSynchronizationObject(name2.c_str(),timeout));
namedLockPattern.releaseSynchronizationObject(name2.c_str());
}
void testOsiSockAddrLockPattern()
{
int64 timeout = 10000;
NamedLockPattern<const osiSockAddr*,comp_osiSockAddrPtr> namedLockPattern;
osiSockAddr name1;
name1.ia.sin_addr.s_addr = 1;
name1.ia.sin_port = 1;
name1.ia.sin_family = AF_INET;
assert(namedLockPattern.acquireSynchronizationObject(&name1,timeout));
assert(namedLockPattern.acquireSynchronizationObject(&name1,timeout));
osiSockAddr name2;
name2.ia.sin_addr.s_addr = 1;
name2.ia.sin_port = 1;
name2.ia.sin_family = AF_INET;
assert(namedLockPattern.acquireSynchronizationObject(&name2,timeout));
assert(namedLockPattern.acquireSynchronizationObject(&name2,timeout));
namedLockPattern.releaseSynchronizationObject(&name1);
namedLockPattern.releaseSynchronizationObject(&name1);
namedLockPattern.releaseSynchronizationObject(&name2);
namedLockPattern.releaseSynchronizationObject(&name2);
osiSockAddr name3;
name3.ia.sin_addr.s_addr = 1;
name3.ia.sin_port = 1;
name3.ia.sin_family = AF_INET;
NamedLock<const osiSockAddr*,comp_osiSockAddrPtr> namedGuard(&namedLockPattern);
assert(namedGuard.acquireSynchronizationObject(&name3,timeout));
}
void testOsiSockAddrWithPtrKeyLockPattern()
{
int64 timeout = 10000;
NamedLockPattern<const osiSockAddr*,comp_osiSockAddrPtr> namedLockPattern;
osiSockAddr* name1 = new osiSockAddr;
name1->ia.sin_addr.s_addr = 1;
name1->ia.sin_port = 1;
name1->ia.sin_family = AF_INET;
assert(namedLockPattern.acquireSynchronizationObject(name1,timeout));
assert(namedLockPattern.acquireSynchronizationObject(name1,timeout));
namedLockPattern.releaseSynchronizationObject(name1);
namedLockPattern.releaseSynchronizationObject(name1);
delete name1;
}
void testWorker1(void* p)
{
int32 timeout = 1000;
const int32 max = 1000;
NamedLockPattern<osiSockAddr,comp_osiSockAddr>* namedLockPattern = (NamedLockPattern<osiSockAddr,comp_osiSockAddr>*)p;
for(int32 i = 0 ; i < max; i = i +2)
{
osiSockAddr addr;
addr.ia.sin_addr.s_addr = i;
addr.ia.sin_port = i;
addr.ia.sin_family = AF_INET;
NamedLock<osiSockAddr,comp_osiSockAddr> namedGuard(namedLockPattern);
assert(namedGuard.acquireSynchronizationObject(addr,timeout));
epicsThreadSleep(1e-6);
}
//this one takes a lock, thread 2 will be slower and will get timeout
{ //due to namedGuard
osiSockAddr addr;
addr.ia.sin_addr.s_addr = 1;
addr.ia.sin_port = 1;
addr.ia.sin_family = AF_INET;
NamedLock<osiSockAddr,comp_osiSockAddr> namedGuard(namedLockPattern);
assert(namedGuard.acquireSynchronizationObject(addr,timeout));
epicsThreadSleep(5.0);
}
int dummy = 1;
epicsMessageQueueSend(join1, &dummy, 1);
}
void testWorker2(void* p)
{
int32 timeout = 1000;
const int32 max = 1000;
NamedLockPattern<osiSockAddr,comp_osiSockAddr>* namedLockPattern = (NamedLockPattern<osiSockAddr,comp_osiSockAddr>*)p;
for(int32 i = 1 ; i < max; i = i + 2)
{
osiSockAddr addr;
addr.ia.sin_addr.s_addr = i;
addr.ia.sin_port = i;
addr.ia.sin_family = AF_INET;
NamedLock<osiSockAddr,comp_osiSockAddr> namedGuard(namedLockPattern);
assert(namedGuard.acquireSynchronizationObject(addr,timeout));
epicsThreadSleep(1e-6);
}
//this thread sleeps a while and gets timeout on lock
{
epicsThreadSleep(1.0);
osiSockAddr addr;
addr.ia.sin_addr.s_addr = 1;
addr.ia.sin_port = 1;
addr.ia.sin_family = AF_INET;
NamedLock<osiSockAddr,comp_osiSockAddr> namedGuard(namedLockPattern);
//TODO swap next two lines if timed lock used
//assert(!namedGuard.acquireSynchronizationObject(addr,timeout));
assert(namedGuard.acquireSynchronizationObject(addr,timeout));
}
int dummy = 2;
epicsMessageQueueSend(join2, &dummy, 1);
}
int main(int argc, char *argv[])
{
testIntLockPattern();
testIntPtrLockPattern();
testCharPtrLockPattern();
testOsiSockAddrLockPattern();
testOsiSockAddrWithPtrKeyLockPattern();
NamedLockPattern<osiSockAddr,comp_osiSockAddr> namedLockPattern;
join1 = epicsMessageQueueCreate(1, 1);
join2 = epicsMessageQueueCreate(1, 1);
//create two threads
epicsThreadId t1 = epicsThreadCreate("worker1", epicsThreadPriorityMedium, epicsThreadGetStackSize(epicsThreadStackMedium),
testWorker1, &namedLockPattern);
assert(t1);
epicsThreadId t2 = epicsThreadCreate("worker2", epicsThreadPriorityMedium, epicsThreadGetStackSize(epicsThreadStackMedium),
testWorker2, &namedLockPattern);
assert(t2);
int dummy;
epicsMessageQueueReceive(join1, &dummy, 1);
epicsMessageQueueReceive(join2, &dummy, 1);
epicsExitCallAtExits();
CDRMonitor::get().show(stdout, true);
return 0;
}