Changeset 21614 for trunk/testapp/threads/threads.c
- Timestamp:
- Apr 14, 2011, 1:07:40 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/testapp/threads/threads.c
r21608 r21614 1 1 /* 2 2 * Taken from here http://msdn.microsoft.com/en-us/library/ms682516%28v=VS.85%29.aspx 3 * and slightly modified to compile with Odin3 * and modified for the needs of the testcase 4 4 */ 5 6 //#define USE_TRY 7 8 #if !defined(_MSC_VER) && 1 9 #define INCL_DOS 10 #include <os2wrap2.h> 11 #endif 5 12 6 13 #include <windows.h> 7 14 #include <tchar.h> 15 #include <excpt.h> 8 16 9 17 #define MAX_THREADS 10 … … 32 40 #ifndef _MSC_VER 33 41 42 // register the EXE to cause the OS/2 exception handler setup around 43 // the entry point 44 45 #include <odinlx.h> 46 47 #undef _tmain 48 int _tmain(); 49 50 int APIENTRY WinMain(HINSTANCE hInstance, 51 HINSTANCE hPrevInstance, 52 LPTSTR lpCmdLine, 53 int nCmdShow) 54 { 55 return _tmain(); 56 } 57 58 int main(int argc, char **argv) 59 { 60 EnableSEH(); 61 RegisterLxExe((WINMAIN)WinMain, NULL); 62 return _tmain(); 63 } 64 34 65 void StringCchPrintf(LPTSTR pszDest, size_t cchDest, 35 66 LPCTSTR pszFormat, ...) 36 67 { 37 68 va_list ap; 38 69 39 70 va_start(ap, pszFormat); 40 71 vsnprintf(pszDest, cchDest, pszFormat, ap); 41 va_end(ap); 72 va_end(ap); 42 73 } 43 74 … … 47 78 } 48 79 49 #endif 80 #endif // !_MSC_VER 50 81 51 82 int _tmain() … … 53 84 PMYDATA pDataArray[MAX_THREADS]; 54 85 DWORD dwThreadIdArray[MAX_THREADS]; 55 HANDLE hThreadArray[MAX_THREADS]; 86 HANDLE hThreadArray[MAX_THREADS]; 56 87 57 88 // Create MAX_THREADS worker threads. … … 80 111 // Create the thread to begin execution on its own. 81 112 82 hThreadArray[i] = CreateThread( 113 hThreadArray[i] = CreateThread( 83 114 NULL, // default security attributes 84 0, // use default stack size 115 0, // use default stack size 85 116 MyThreadFunction, // thread function name 86 pDataArray[i], // argument to thread function 87 0, // use default creation flags 88 &dwThreadIdArray[i]); // returns the thread identifier 117 pDataArray[i], // argument to thread function 118 0, // use default creation flags 119 &dwThreadIdArray[i]); // returns the thread identifier 89 120 90 121 91 122 // Check the return value for success. 92 // If CreateThread fails, terminate execution. 93 // This will automatically clean up threads and memory. 94 95 if (hThreadArray[i] == NULL) 123 // If CreateThread fails, terminate execution. 124 // This will automatically clean up threads and memory. 125 126 if (hThreadArray[i] == NULL) 96 127 { 97 128 ErrorHandler(TEXT("CreateThread")); … … 100 131 } // End of main thread creation loop. 101 132 102 #ifndef _MSC_VER 103 printf("Started %d threads. Waiting for them to terminate...\n", MAX_THREADS); 104 #endif 105 106 // Wait until all threads have terminated. 107 108 WaitForMultipleObjects(MAX_THREADS, hThreadArray, TRUE, INFINITE); 109 110 #ifndef _MSC_VER 111 printf("All threads terminated.\n"); 112 #endif 113 133 _tprintf(TEXT("Started %d threads. Waiting for them to terminate...\n"), 134 MAX_THREADS); 135 136 // Wait until some threads have terminated. 137 138 WaitForMultipleObjects(MAX_THREADS, hThreadArray, TRUE, 2000); 139 140 _tprintf(TEXT("Finished waiting.\n")); 141 114 142 // Close all thread handles and free memory allocations. 115 143 … … 124 152 } 125 153 154 #if !defined(_MSC_VER) && 1 155 DosExit(1, 0); 156 #endif 157 126 158 return 0; 127 159 } 128 160 129 130 DWORD WINAPI MyThreadFunction( LPVOID lpParam ) 131 { 132 HANDLE hStdout; 161 #ifdef USE_TRY 162 int exc_filter(DWORD code, PEXCEPTION_POINTERS pPtrs) 163 { 164 PEXCEPTION_RECORD pRec = pPtrs->ExceptionRecord; 165 166 #ifndef _MSC_VER 167 os2_PPIB pPib; 168 os2_PTIB pTib; 169 DosGetInfoBlocks(&pTib, &pPib); 170 printf("TID: %d\n", pTib->tib_ptib2->tib2_ultid); 171 #endif 172 173 _tprintf(TEXT("Filter: code %08lx\n"), code); 174 _tprintf(TEXT("ExceptionCode %p\n"), pRec->ExceptionCode); 175 _tprintf(TEXT("ExceptionAddress %p\n"), pRec->ExceptionAddress); 176 _tprintf(TEXT("NumberParameters %d\n"), pRec->NumberParameters); 177 178 return EXCEPTION_CONTINUE_SEARCH; 179 } 180 #endif 181 182 DWORD WINAPI MyThreadFunction( LPVOID lpParam ) 183 { 133 184 PMYDATA pDataArray; 134 185 … … 137 188 DWORD dwChars; 138 189 139 // Make sure there is a console to receive output results. 140 141 hStdout = GetStdHandle(STD_OUTPUT_HANDLE); 142 if( hStdout == INVALID_HANDLE_VALUE ) 143 return 1; 144 145 // Cast the parameter to the correct data type. 146 // The pointer is known to be valid because 147 // it was checked for NULL before the thread was created. 148 149 pDataArray = (PMYDATA)lpParam; 150 151 // Print the parameter values using thread-safe functions. 152 153 Sleep(1000 * pDataArray->val1 / 2); 154 155 StringCchPrintf(msgBuf, BUF_SIZE, TEXT("Parameters = %d, %d\n"), 156 pDataArray->val1, pDataArray->val2); 157 StringCchLength(msgBuf, BUF_SIZE, &cchStringSize); 158 #ifdef _MSC_VER 159 WriteConsole(hStdout, msgBuf, (DWORD)cchStringSize, &dwChars, NULL); 160 #else 161 // WriteConsole seems to be a stub in Odin yet 162 printf("%s", msgBuf); 163 #endif 190 #ifdef USE_TRY 191 __try 192 { 193 #endif 194 // Cast the parameter to the correct data type. 195 // The pointer is known to be valid because 196 // it was checked for NULL before the thread was created. 197 198 pDataArray = (PMYDATA)lpParam; 199 200 // Print the parameter values using thread-safe functions. 201 202 Sleep(1000 * pDataArray->val1 / 2); 164 203 165 204 #if 0 166 // crash the application 167 if (pDataArray->val1 == 6) 168 { 169 *((int*)0) = 0; 205 StringCchPrintf(msgBuf, BUF_SIZE, TEXT("Parameters = %d, %d\n"), 206 pDataArray->val1, pDataArray->val2); 207 _tprintf("%s", msgBuf); 208 #endif 209 210 #ifdef USE_TRY 170 211 } 171 #endif 172 173 return 0; 174 } 175 176 177 178 void ErrorHandler(LPTSTR lpszFunction) 179 { 212 __except(exc_filter(exception_code(), exception_info())) 213 { 214 } 215 #endif 216 217 return 0; 218 } 219 220 void ErrorHandler(LPTSTR lpszFunction) 221 { 180 222 // Retrieve the system error message for the last-error code. 181 223 182 224 LPVOID lpMsgBuf; 183 225 LPVOID lpDisplayBuf; 184 DWORD dw = GetLastError(); 226 DWORD dw = GetLastError(); 185 227 186 228 FormatMessage( 187 FORMAT_MESSAGE_ALLOCATE_BUFFER | 229 FORMAT_MESSAGE_ALLOCATE_BUFFER | 188 230 FORMAT_MESSAGE_FROM_SYSTEM | 189 231 FORMAT_MESSAGE_IGNORE_INSERTS, … … 196 238 // Display the error message. 197 239 198 lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, 199 (lstrlen((LPCTSTR) lpMsgBuf) + lstrlen((LPCTSTR) lpszFunction) + 40) * sizeof(TCHAR)); 200 StringCchPrintf((LPTSTR)lpDisplayBuf, 240 lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, 241 (lstrlen((LPCTSTR) lpMsgBuf) + lstrlen((LPCTSTR) lpszFunction) + 40) * sizeof(TCHAR)); 242 StringCchPrintf((LPTSTR)lpDisplayBuf, 201 243 LocalSize(lpDisplayBuf) / sizeof(TCHAR), 202 TEXT("%s failed with error %d: %s"), 203 lpszFunction, dw, lpMsgBuf); 204 MessageBox(NULL, (LPCTSTR) lpDisplayBuf, TEXT("Error"), MB_OK); 244 TEXT("%s failed with error %d: %s"), 245 lpszFunction, dw, lpMsgBuf); 246 MessageBox(NULL, (LPCTSTR) lpDisplayBuf, TEXT("Error"), MB_OK); 205 247 206 248 // Free error-handling buffer allocations.
Note:
See TracChangeset
for help on using the changeset viewer.