1 #include <TestShell.h> 2 #include <ThreadedTestCase.h> 3 #include <Autolock.h> 4 #include <stdio.h> 5 6 BThreadedTestCase::BThreadedTestCase(std::string name, std::string progressSeparator) 7 : BTestCase(name) 8 , fProgressSeparator(progressSeparator) 9 , fUpdateLock(new BLocker()) 10 { 11 } 12 13 BThreadedTestCase::~BThreadedTestCase() { 14 // Kill our locker 15 delete fUpdateLock; 16 17 // Clean up 18 for (std::map<thread_id, ThreadSubTestInfo*>::iterator i = fNumberMap.begin(); 19 i != fNumberMap.end(); 20 i++) 21 { 22 delete i->second; 23 } 24 } 25 26 void 27 BThreadedTestCase::NextSubTest() { 28 // Find out what thread we're in 29 thread_id id = find_thread(NULL); 30 31 { 32 // Acquire the update lock 33 BAutolock lock(fUpdateLock); 34 std::map<thread_id, ThreadSubTestInfo*>::iterator i = fNumberMap.find(id); 35 if (i != fNumberMap.end() && i->second) { 36 // Handle multi-threaded case 37 ThreadSubTestInfo *info = i->second; 38 char num[32]; 39 sprintf(num, "%ld", info->subTestNum++); 40 std::string str = std::string("[") + info->name + fProgressSeparator + num + "]"; 41 fUpdateList.push_back(str); 42 return; 43 } 44 } 45 46 // Handle single-threaded case 47 BTestCase::NextSubTest(); 48 } 49 50 void 51 BThreadedTestCase::Outputf(const char *str, ...) { 52 if (BTestShell::GlobalBeVerbose()) { 53 // Figure out if this is a multithreaded test or not 54 thread_id id = find_thread(NULL); 55 bool isSingleThreaded; 56 { 57 BAutolock lock(fUpdateLock); 58 isSingleThreaded = fNumberMap.find(id) == fNumberMap.end(); 59 } 60 if (isSingleThreaded) { 61 va_list args; 62 va_start(args, str); 63 vprintf(str, args); 64 va_end(args); 65 fflush(stdout); 66 } else { 67 va_list args; 68 va_start(args, str); 69 char msg[1024]; // Need a longer string? Change the constant or change the function. :-) 70 vsprintf(msg, str, args); 71 va_end(args); 72 { 73 // Acquire the update lock and post our update 74 BAutolock lock(fUpdateLock); 75 fUpdateList.push_back(std::string(msg)); 76 } 77 } 78 } 79 } 80 81 void 82 BThreadedTestCase::InitThreadInfo(thread_id id, std::string threadName) { 83 BAutolock lock(fUpdateLock); // Lock the number map 84 std::map<thread_id, ThreadSubTestInfo*>::iterator i = fNumberMap.find(id); 85 if (i != fNumberMap.end() && i->second) { 86 i->second->name = threadName; 87 i->second->subTestNum = 0; 88 } else { 89 // New addition 90 ThreadSubTestInfo *info = new ThreadSubTestInfo(); 91 info->name = threadName; 92 info->subTestNum = 0; 93 fNumberMap[id] = info; 94 } 95 } 96 97 bool 98 BThreadedTestCase::RegisterForUse() { 99 if (!fInUse) { 100 fInUse = true; 101 return true; 102 } else 103 return false; 104 } 105 106 void 107 BThreadedTestCase::UnregisterForUse() { 108 fInUse = false; 109 } 110 111 std::vector<std::string>& 112 BThreadedTestCase::AcquireUpdateList() { 113 fUpdateLock->Lock(); 114 return fUpdateList; 115 } 116 117 void 118 BThreadedTestCase::ReleaseUpdateList() { 119 fUpdateLock->Unlock(); 120 } 121