Ignore:
Timestamp:
Apr 14, 2011, 1:07:40 PM (14 years ago)
Author:
dmik
Message:

testapp/threads: Updated to properly trigger the hanging behavior (#28).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/testapp/threads/threads.c

    r21608 r21614  
    11/*
    22 * Taken from here http://msdn.microsoft.com/en-us/library/ms682516%28v=VS.85%29.aspx
    3  * and slightly modified to compile with Odin
     3 * and modified for the needs of the testcase
    44 */
     5
     6//#define USE_TRY
     7
     8#if !defined(_MSC_VER) && 1
     9#define INCL_DOS
     10#include <os2wrap2.h>
     11#endif
    512
    613#include <windows.h>
    714#include <tchar.h>
     15#include <excpt.h>
    816
    917#define MAX_THREADS 10
     
    3240#ifndef _MSC_VER
    3341
     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
     48int _tmain();
     49
     50int APIENTRY WinMain(HINSTANCE hInstance,
     51                     HINSTANCE hPrevInstance,
     52                     LPTSTR    lpCmdLine,
     53                     int       nCmdShow)
     54{
     55    return _tmain();
     56}
     57
     58int main(int argc, char **argv)
     59{
     60    EnableSEH();
     61    RegisterLxExe((WINMAIN)WinMain, NULL);
     62    return _tmain();
     63}
     64
    3465void StringCchPrintf(LPTSTR pszDest, size_t cchDest,
    3566                     LPCTSTR pszFormat, ...)
    3667{
    3768    va_list ap;
    38    
     69
    3970    va_start(ap, pszFormat);
    4071    vsnprintf(pszDest, cchDest, pszFormat, ap);
    41     va_end(ap);   
     72    va_end(ap);
    4273}
    4374
     
    4778}
    4879
    49 #endif
     80#endif // !_MSC_VER
    5081
    5182int _tmain()
     
    5384    PMYDATA pDataArray[MAX_THREADS];
    5485    DWORD   dwThreadIdArray[MAX_THREADS];
    55     HANDLE  hThreadArray[MAX_THREADS]; 
     86    HANDLE  hThreadArray[MAX_THREADS];
    5687
    5788    // Create MAX_THREADS worker threads.
     
    80111        // Create the thread to begin execution on its own.
    81112
    82         hThreadArray[i] = CreateThread( 
     113        hThreadArray[i] = CreateThread(
    83114            NULL,                   // default security attributes
    84             0,                      // use default stack size 
     115            0,                      // use default stack size
    85116            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
    89120
    90121
    91122        // 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)
    96127        {
    97128           ErrorHandler(TEXT("CreateThread"));
     
    100131    } // End of main thread creation loop.
    101132
    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
    114142    // Close all thread handles and free memory allocations.
    115143
     
    124152    }
    125153
     154#if !defined(_MSC_VER) && 1
     155    DosExit(1, 0);
     156#endif
     157
    126158    return 0;
    127159}
    128160
    129 
    130 DWORD WINAPI MyThreadFunction( LPVOID lpParam )
    131 {
    132     HANDLE hStdout;
     161#ifdef USE_TRY
     162int 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
     182DWORD WINAPI MyThreadFunction( LPVOID lpParam )
     183{
    133184    PMYDATA pDataArray;
    134185
     
    137188    DWORD dwChars;
    138189
    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);
    164203
    165204#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
    170211    }
    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
     220void ErrorHandler(LPTSTR lpszFunction)
     221{
    180222    // Retrieve the system error message for the last-error code.
    181223
    182224    LPVOID lpMsgBuf;
    183225    LPVOID lpDisplayBuf;
    184     DWORD dw = GetLastError(); 
     226    DWORD dw = GetLastError();
    185227
    186228    FormatMessage(
    187         FORMAT_MESSAGE_ALLOCATE_BUFFER | 
     229        FORMAT_MESSAGE_ALLOCATE_BUFFER |
    188230        FORMAT_MESSAGE_FROM_SYSTEM |
    189231        FORMAT_MESSAGE_IGNORE_INSERTS,
     
    196238    // Display the error message.
    197239
    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,
    201243        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);
    205247
    206248        // Free error-handling buffer allocations.
Note: See TracChangeset for help on using the changeset viewer.