home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: WPS_PM / WPS_PM.zip / xfld085s.zip / helpers / threads.c < prev    next >
C/C++ Source or Header  |  1999-02-23  |  7KB  |  235 lines

  1.  
  2. /*
  3.  *@@sourcefile threads.c:
  4.  *      contains helper functions for creating, destroying, and
  5.  *      synchronizing threads.
  6.  *
  7.  *      Function prefixes (new with V0.81):
  8.  *      --  thr*        Thread helper functions
  9.  *
  10.  *      This file is new with V0.81 and contains all the thread
  11.  *      functions that used to be in helpers.c.
  12.  *
  13.  *@@include #define INCL_DOSPROCESS
  14.  *@@include #include <os2.h>
  15.  *@@include #include "threads.h"
  16.  */
  17.  
  18. /*
  19.  *      Copyright (C) 1997-99 Ulrich Möller.
  20.  *      This file is part of the XFolder source package.
  21.  *      XFolder is free software; you can redistribute it and/or modify
  22.  *      it under the terms of the GNU General Public License as published
  23.  *      by the Free Software Foundation, in version 2 as it comes in the
  24.  *      "COPYING" file of the XFolder main distribution.
  25.  *      This program is distributed in the hope that it will be useful,
  26.  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
  27.  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  28.  *      GNU General Public License for more details.
  29.  */
  30.  
  31. #define INCL_DOSPROCESS
  32. #define INCL_DOSERRORS
  33. #include <os2.h>
  34.  
  35. #include <stdlib.h>
  36.  
  37. #include "threads.h"
  38.  
  39. /*
  40.  *@@ thrCreate:
  41.  *      this function creates a THREADINFO structure in *ppti;
  42.  *      you must pass the thread function in pfn, which will
  43.  *      then be executed. The thread will be passed a pointer
  44.  *      to the new THREADINFO structure as its thread parameter.
  45.  *      The ulData field in that structure is set to ulData
  46.  *      here. Use whatever you like.
  47.  *      Note: As opposed to previous versions, V0.84 now expects
  48.  *      *pfn to have _Optlink calling convention, because now
  49.  *      _beginthread() is used instead of DosCreateThread().
  50.  */
  51.  
  52. BOOL thrCreate(PTHREADINFO *ppti,   // out: where to create THREADINFO
  53.                PTHREADFUNC pfn,     // in: _Optlink thread function
  54.                ULONG ulData)        // in: user data to be stored in THREADINFO
  55. {
  56.     BOOL            rc = FALSE;
  57.     PTHREADINFO     pti = NULL;
  58.  
  59.     if (ppti)
  60.     {
  61.         if (*ppti == NULL)
  62.             pti = (PTHREADINFO)malloc(sizeof(THREADINFO));
  63.         else
  64.             if ((*ppti)->tid == NULLHANDLE)
  65.                 pti = *ppti;
  66.  
  67.         if (pti) {
  68.             // we arrive here if *ppti was NULL or (*ppti->tid == NULLHANDLE),
  69.             // i.e. the thread is not already running. We use
  70.             // DosCreateThread and not _beginthread because we
  71.             // do not use the compiler's default exception handlers,
  72.             // but our own ones for each thread we create, so there.
  73.             // _beginthread is contained both in the VAC++ and EMX
  74.             // C libraries with this syntax.
  75.             pti->tid = _beginthread(
  76.                             pfn,
  77.                             0,      // unused compatibility param
  78.                             65536,  // stack size
  79.                             pti);    // parameter passed to thread
  80.             pti->cb = sizeof(THREADINFO);
  81.             pti->ulData = ulData;
  82.             pti->fExit = FALSE;
  83.  
  84.             pti->hab = NULLHANDLE;
  85.             pti->fExitComplete = FALSE;
  86.             pti->ulResult = 0;
  87.             pti->ulFuncInfo = 0;
  88.             rc = TRUE;
  89.         }
  90.         *ppti = pti;
  91.     }
  92.     return (rc);
  93. }
  94.  
  95. /*
  96.  *@@ thrClose:
  97.  *      this functions sets the "fExit" flag in
  98.  *      THREADINFO to TRUE;
  99.  *      the thread should monitor this flag
  100.  *      periodically and then terminate itself.
  101.  */
  102.  
  103. BOOL thrClose(PTHREADINFO pti)
  104. {
  105.     if (pti) {
  106.         pti->fExit = TRUE;
  107.         return (TRUE);
  108.     }
  109.     return (FALSE);
  110. }
  111.  
  112. /*
  113.  *@@ thrGoodbye:
  114.  *      every thread should call this function just before
  115.  *      it terminates itself so that the other thread funcs
  116.  *      can react properly. This updates the THREADINFO
  117.  *      structure, but does _not_ call _endthread(). So you
  118.  *      should either call this function before calling
  119.  *      _endthread() or as the last function call in the
  120.  *      thread function itself before it exits.
  121.  */
  122.  
  123. VOID thrGoodbye(PTHREADINFO pti)
  124. {
  125.     if (pti) {
  126.         pti->fExitComplete = TRUE;
  127.         pti->tid = NULLHANDLE;
  128.     }
  129. }
  130.  
  131. /*
  132.  *@@ thrWait:
  133.  *      this function waits for a thread to end by calling
  134.  *      DosWaitThread. Note that this blocks the calling
  135.  *      thread, so only use this function when you're sure
  136.  *      the thread will actually terminate.
  137.  */
  138.  
  139. BOOL thrWait(PTHREADINFO pti)
  140. {
  141.     if (pti) {
  142.         DosWaitThread(&(pti->tid), DCWW_WAIT);
  143.         pti->tid = NULLHANDLE;
  144.         return (TRUE);
  145.     }
  146.     return (FALSE);
  147. }
  148.  
  149. /*
  150.  *@@ thrFree:
  151.  *      this is a combination of thrClose and
  152.  *      thrWait; the THREADINFO block is then freed
  153.  *      and *ppti set to NULL.
  154.  */
  155.  
  156. BOOL thrFree(PTHREADINFO *ppti)
  157. {
  158.     if (ppti)
  159.         if (*ppti) {
  160.             if ((*ppti)->tid) {
  161.                 thrClose(*ppti);
  162.                 thrWait(*ppti);
  163.             }
  164.             free(*ppti);
  165.             *ppti = NULL;
  166.             return (TRUE);
  167.         }
  168.  
  169.     return (FALSE);
  170. }
  171.  
  172. /*
  173.  *@@ thrKill:
  174.  *      just like thrFree, but the thread is
  175.  *      brutally killed, using DosKillThread.
  176.  */
  177.  
  178. BOOL thrKill(PTHREADINFO *ppti)
  179. {
  180.     if (ppti)
  181.         if (*ppti) {
  182.             if ((*ppti)->tid) {
  183.                 DosResumeThread((*ppti)->tid);
  184.                     // this returns an error if the thread
  185.                     // is not suspended, but otherwise the
  186.                     // system might hang
  187.                 DosKillThread((*ppti)->tid);
  188.             }
  189.             free(*ppti);
  190.             *ppti = NULL;
  191.             return (TRUE);
  192.         }
  193.     return (FALSE);
  194. }
  195.  
  196. /*
  197.  *@@ thrQueryID:
  198.  *      returns thread ID.
  199.  */
  200.  
  201. TID thrQueryID(PTHREADINFO pti)
  202. {
  203.     if (pti)
  204.         if (!(pti->fExitComplete))
  205.             return (pti->tid);
  206.  
  207.     return NULLHANDLE;
  208. }
  209.  
  210. /*
  211.  *@@ thrQueryPriority:
  212.  *      returns the priority of the calling thread.
  213.  *      The low byte of the low word is a hexadecimal value
  214.  *      representing a rank (value 0 to 31) within a priority class.
  215.  *      Class values, found in the high byte of the low word, are
  216.  *      as follows:
  217.  *          0x01  idle
  218.  *          0x02  regular
  219.  *          0x03  time-critical
  220.  *          0x04  server
  221.  */
  222.  
  223. ULONG thrQueryPriority(VOID)
  224. {
  225.     PTIB    ptib;
  226.     PPIB    ppib;
  227.     if (DosGetInfoBlocks(&ptib, &ppib) == NO_ERROR)
  228.         if (ptib)
  229.             if (ptib->tib_ptib2)
  230.                 return (ptib->tib_ptib2->tib2_ulpri);
  231.     return (0);
  232. }
  233.  
  234.  
  235.