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