#include <TestShell.h>
#include <ThreadedTestCase.h>
#include <Autolock.h>
#include <stdio.h>
#include <stdarg.h>
using std::map;
using std::string;
using std::vector;
_EXPORT
BThreadedTestCase::BThreadedTestCase(string name, string progressSeparator)
: BTestCase(name)
, fInUse(false)
, fProgressSeparator(progressSeparator)
, fUpdateLock(new BLocker())
{
}
_EXPORT
BThreadedTestCase::~BThreadedTestCase() {
delete fUpdateLock;
for (map<thread_id, ThreadSubTestInfo*>::iterator i = fNumberMap.begin();
i != fNumberMap.end(); i++)
{
delete i->second;
}
}
_EXPORT
void
BThreadedTestCase::NextSubTest() {
thread_id id = find_thread(NULL);
{
BAutolock lock(fUpdateLock);
map<thread_id, ThreadSubTestInfo*>::iterator i = fNumberMap.find(id);
if (i != fNumberMap.end() && i->second) {
ThreadSubTestInfo *info = i->second;
char num[32];
sprintf(num, "%" B_PRId32 "", info->subTestNum++);
string str = string("[") + info->name + fProgressSeparator + num
+ "]";
fUpdateList.push_back(str);
return;
}
}
BTestCase::NextSubTest();
}
_EXPORT
void
BThreadedTestCase::Outputf(const char *str, ...) {
if (BTestShell::GlobalBeVerbose()) {
thread_id id = find_thread(NULL);
bool isSingleThreaded;
{
BAutolock lock(fUpdateLock);
isSingleThreaded = fNumberMap.find(id) == fNumberMap.end();
}
if (isSingleThreaded) {
va_list args;
va_start(args, str);
vprintf(str, args);
va_end(args);
fflush(stdout);
} else {
va_list args;
va_start(args, str);
char msg[1024];
vsprintf(msg, str, args);
va_end(args);
{
BAutolock lock(fUpdateLock);
fUpdateList.push_back(string(msg));
}
}
}
}
_EXPORT
void
BThreadedTestCase::InitThreadInfo(thread_id id, string threadName) {
BAutolock lock(fUpdateLock);
map<thread_id, ThreadSubTestInfo*>::iterator i = fNumberMap.find(id);
if (i != fNumberMap.end() && i->second) {
i->second->name = threadName;
i->second->subTestNum = 0;
} else {
ThreadSubTestInfo *info = new ThreadSubTestInfo();
info->name = threadName;
info->subTestNum = 0;
fNumberMap[id] = info;
}
}
_EXPORT
bool
BThreadedTestCase::RegisterForUse() {
if (!fInUse) {
fInUse = true;
return true;
} else
return false;
}
_EXPORT
void
BThreadedTestCase::UnregisterForUse() {
fInUse = false;
}
_EXPORT
vector<string>&
BThreadedTestCase::AcquireUpdateList() {
fUpdateLock->Lock();
return fUpdateList;
}
_EXPORT
void
BThreadedTestCase::ReleaseUpdateList() {
fUpdateLock->Unlock();
}