Ignore:
Timestamp:
Mar 8, 2001, 8:28:45 PM (24 years ago)
Author:
umoeller
Message:

Misc. changes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/helpers/threads.c

    r38 r44  
    5050#include "setup.h"                      // code generation and debugging options
    5151
     52#include "helpers\linklist.h"
    5253#include "helpers\threads.h"
    5354
     
    5859 *      see threads.c.
    5960 */
     61
     62/* ******************************************************************
     63 *
     64 *   Global variables
     65 *
     66 ********************************************************************/
     67
     68LINKLIST        G_llThreadInfos;
     69            // linked list of all THREADINFOS ever created...
     70            // no auto-free
     71HMTX            G_hmtxThreadInfos = NULLHANDLE;
     72
     73/* ******************************************************************
     74 *
     75 *   Functions
     76 *
     77 ********************************************************************/
     78
     79/*
     80 *@@ LockThreadInfos:
     81 *
     82 *@@added V0.9.9 (2001-03-07) [umoeller]
     83 */
     84
     85BOOL LockThreadInfos(VOID)
     86{
     87    APIRET arc = NO_ERROR;
     88
     89    if (G_hmtxThreadInfos == NULLHANDLE)
     90    {
     91        // first call:
     92        arc = DosCreateMutexSem(NULL,     // unnamed
     93                                &G_hmtxThreadInfos,
     94                                0,        // unshared
     95                                TRUE);        // request!
     96        lstInit(&G_llThreadInfos, FALSE);
     97    }
     98    else
     99    {
     100        arc = DosRequestMutexSem(G_hmtxThreadInfos,
     101                                 SEM_INDEFINITE_WAIT);
     102    }
     103
     104    return (arc == NO_ERROR);
     105}
     106
     107/*
     108 *@@ UnlockThreadInfos:
     109 *
     110 *@@added V0.9.9 (2001-03-07) [umoeller]
     111 */
     112
     113VOID UnlockThreadInfos(VOID)
     114{
     115    DosReleaseMutexSem(G_hmtxThreadInfos);
     116}
    60117
    61118/*
     
    108165            DosCloseEventSem(pti->hevRunning);
    109166
     167        // V0.9.9 (2001-03-07) [umoeller]
     168        // remove thread from global list
     169        if (LockThreadInfos())
     170        {
     171            lstRemoveItem(&G_llThreadInfos, pti);
     172            UnlockThreadInfos();
     173        }
     174
    110175        // (2000-12-18) [lafaix] clean up pti if thread is transient.
    111176        if (pti->flFlags & THRF_TRANSIENT)
     
    128193/*
    129194 *@@ thrCreate:
    130  *      this function fills a THREADINFO structure in *pti
    131  *      and starts a new thread using _beginthread.
     195 *      this function fills a THREADINFO structure and starts
     196 *      a new thread using _beginthread.
    132197 *
    133198 *      You must pass the thread function in pfn, which will
     
    144209 *      function is prototyped somewhere, VAC will automatically
    145210 *      modify the function's linkage, and you'll run into
    146  *      compiler warnings.
    147  *
    148  *      ptiMyself is then a pointer to the THREADINFO structure.
     211 *      crashes.
     212 *
     213 *      The thread's ptiMyself is then a pointer to the
     214 *      THREADINFO structure passed to this function.
    149215 *      ulData may be obtained like this:
    150  +          ULONG ulData = ((PTHREADINFO)ptiMyself)->ulData;
     216 *
     217 +          ULONG ulData = ptiMyself->ulData;
     218 *
     219 *      The THREADINFO structure passed to this function must
     220 *      be accessible all the time while the thread is running
     221 *      because the thr* functions will use it for maintenance.
     222 *
     223 *      This function does NOT check whether a thread is
     224 *      already running in *pti. Do not use the same THREADINFO
     225 *      for several threads.
     226 *
     227 *      If you do not want to manage the structure yourself,
     228 *      you can pass the THRF_TRANSIENT flag (see below).
    151229 *
    152230 *      thrCreate does not call your thread func directly,
     
    156234 *      explicitly, because this would skip the exit processing
    157235 *      (cleanup) in thr_fntGeneric. Instead, just fall out of
    158  *      your thread function.
    159  *
    160  *      This function does NOT check whether a thread is
    161  *      already running in *pti. If it is, that information
    162  *      will be lost.
     236 *      your thread function, or return().
    163237 *
    164238 *      flFlags can be any combination of the following:
     
    194268 *@@changed V0.9.7 (2000-12-18) [lafaix]: THRF_TRANSIENT support added
    195269 *@@changed V0.9.9 (2001-02-06) [umoeller]: now returning TID
     270 *@@changed V0.9.9 (2001-03-07) [umoeller]: added pcszThreadName
    196271 */
    197272
     
    200275                PBOOL pfRunning,     // out: variable set to TRUE while thread is running;
    201276                                     // ptr can be NULL
     277                const char *pcszThreadName, // in: thread name (for identification)
    202278                ULONG flFlags,       // in: THRF_* flags
    203279                ULONG ulData)        // in: user data to be stored in THREADINFO
     
    209285    {
    210286        if (pti == NULL)
    211             pti = (PTHREADINFO) malloc(sizeof(THREADINFO));
     287            pti = (PTHREADINFO)malloc(sizeof(THREADINFO));
     288                    // cleaned up by thr_fntGeneric on exit
    212289    }
    213290
    214291    if (pti)
    215292    {
    216         // we arrive here if *ppti was NULL or (*ppti->tid == NULLHANDLE),
    217         // i.e. the thread is not already running.
    218         // _beginthread is contained both in the VAC++ and EMX
    219         // C libraries with this syntax.
    220293        memset(pti, 0, sizeof(THREADINFO));
    221294        pti->cbStruct = sizeof(THREADINFO);
    222295        pti->pThreadFunc = (PVOID)pfn;
    223296        pti->pfRunning = pfRunning;
     297        pti->pcszThreadName = pcszThreadName; // V0.9.9 (2001-03-07) [umoeller]
    224298        pti->flFlags = flFlags;
    225299        pti->ulData = ulData;
     
    251325
    252326            if (ulrc)
     327            {
     328                if (LockThreadInfos())
     329                {
     330                    lstAppendItem(&G_llThreadInfos, pti);
     331                    UnlockThreadInfos();
     332                }
     333
    253334                if (flFlags & THRF_WAIT)
    254335                {
     
    258339                                    SEM_INDEFINITE_WAIT);
    259340                }
     341            }
    260342        }
    261343    }
     
    281363 *
    282364 *@@added V0.9.5 (2000-08-26) [umoeller]
     365 *@@changed V0.9.9 (2001-03-07) [umoeller]: added pcszThreadName
    283366 */
    284367
    285368ULONG thrRunSync(HAB hab,               // in: anchor block of calling thread
    286                  PTHREADFUNC pfn,       // in: thread function
    287                  ULONG ulData)          // in: data for thread function
     369                 PTHREADFUNC pfn,       // in: passed to thrCreate
     370                 const char *pcszThreadName, // in: passed to thrCreate
     371                 ULONG ulData)          // in: passed to thrCreate
    288372{
    289373    ULONG ulrc = 0;
     
    306390                  pfn,
    307391                  NULL,
     392                  pcszThreadName,
    308393                  THRF_PMMSGQUEUE,
    309394                  ulData);
     
    336421
    337422    return (ulrc);
     423}
     424
     425/*
     426 *@@ thrListThreads:
     427 *      returns an array of THREADINFO structures
     428 *      for all threads that have been started using
     429 *      thrCreate (or thrRunSync).
     430 *
     431 *      If no threads are running yet, this returns
     432 *      NULL.
     433 *
     434 *      Otherwise, this returns the pointer to the
     435 *      first array item, and *pcThreads receives
     436 *      the array item count (NOT the total array
     437 *      size). The array is a copied snapshot of all
     438 *      current THREADINFO's and must be free()'d
     439 *      by the caller.
     440 *
     441 *@@added V0.9.9 (2001-03-07) [umoeller]
     442 */
     443
     444PTHREADINFO thrListThreads(PULONG pcThreads)
     445{
     446    PTHREADINFO pArray = 0;
     447
     448    if (LockThreadInfos())
     449    {
     450        PTHREADINFO pThis;
     451        PLISTNODE pNode;
     452        *pcThreads = lstCountItems(&G_llThreadInfos);
     453        _Pmpf((__FUNCTION__ ": got %d threads", *pcThreads));
     454        pArray = (PTHREADINFO)malloc(*pcThreads * sizeof(THREADINFO));
     455        pThis = pArray;
     456
     457        pNode = lstQueryFirstNode(&G_llThreadInfos);
     458        while (pNode)
     459        {
     460            memcpy(pThis,
     461                   (PTHREADINFO)pNode->pItemData,
     462                   sizeof(THREADINFO));
     463            pThis++;
     464            pNode = pNode->pNext;
     465        }
     466
     467        UnlockThreadInfos();
     468    }
     469
     470    return (pArray);
     471}
     472
     473/*
     474 *@@ thrFindThread:
     475 *      attempts to find the thread with the specified
     476 *      TID; if found, returns TRUE and copies its
     477 *      THREADINFO into *pti.
     478 *
     479 *@@added V0.9.9 (2001-03-07) [umoeller]
     480 */
     481
     482BOOL thrFindThread(PTHREADINFO pti,
     483                   ULONG tid)
     484{
     485    BOOL brc = FALSE;
     486    if (LockThreadInfos())
     487    {
     488        PLISTNODE pNode = lstQueryFirstNode(&G_llThreadInfos);
     489        while (pNode)
     490        {
     491            PTHREADINFO ptiThis = (PTHREADINFO)pNode->pItemData;
     492            if (ptiThis->tid == tid)
     493            {
     494                memcpy(pti, ptiThis, sizeof(THREADINFO));
     495                brc = TRUE;
     496                break;
     497            }
     498            pNode = pNode->pNext;
     499        }
     500
     501        UnlockThreadInfos();
     502    }
     503
     504    return (brc);
    338505}
    339506
Note: See TracChangeset for help on using the changeset viewer.