home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / GETSCRN.EXE / SOURCE / THREAD.C < prev   
Text File  |  1990-06-24  |  8KB  |  292 lines

  1. /*
  2.  
  3.  
  4.  
  5.                                 THREAD.c
  6.  
  7.  
  8.         Copyright (c) 1990 by:  Arthur Kevin McGrath
  9.                                 P. O. Box 128
  10.                                 Barboursville, VA  22923
  11.  
  12.                                 703/832-7025
  13.  
  14.  
  15.   ALL RIGHTS ARE RESERVED.  You may not copy this program in any way
  16.   except to make back-up copies FOR YOUR OWN USE.  If you copy this
  17.   program for any reason without WRITTEN PERMISSION from the above
  18.   named copyright owner (except to make back-up copies FOR YOUR OWN USE),
  19.   you are breaking the Copyright Laws of the United States.  You will go
  20.   to jail for one year and pay a 50,000 fine.
  21.  
  22.  
  23.  
  24.  
  25. */
  26.  
  27.  
  28. #include        <stdio.h>
  29.  
  30. #define INCL_WIN
  31. #define INCL_GPI
  32. #define INCL_BASE
  33. #include <os2.h>
  34.  
  35. #include        "capture.h"
  36.  
  37.  
  38. /*      THREAD_COPY() is a function that takes the place of the
  39.         standard library function strcpy() which does not always
  40.         work in a thread.
  41.  
  42.         It requires the following parameters:
  43.                 char *destination       where will everything be
  44.                                         copied TO
  45.                 char *source            where will everything be
  46.                                         copied FROM             */
  47. void    thread_copy( char *destination, char *source )
  48. {
  49.         while( *source )
  50.         {
  51.                 *destination = *source;
  52.                 destination++;
  53.                 source++;
  54.  
  55.         }
  56.  
  57.         /*      Terminate the destination string.       */
  58.         *destination = '\0';
  59.  
  60. }
  61.  
  62.  
  63.  
  64.  
  65. /*      THREAD_CAT() is a function that takes the place of the
  66.         standard library routine strcat() which does not always
  67.         work when called from a thread.
  68.  
  69.         This routine requires the following parameters:
  70.                 char *destination       where will everything be
  71.                                         concatenated TO
  72.                 char *source            what will be added to the
  73.                                         end of the destination string. */
  74. void    thread_cat( char *destination, char *source )
  75. {
  76.         /*      Get to the end of the destination string.       */
  77.         while( *destination )
  78.         {
  79.                 destination++;
  80.  
  81.         }
  82.  
  83.         /*      Copy the new stuff to the end of the destination.       */
  84.         thread_copy( destination, source );
  85.  
  86. }
  87.  
  88.  
  89.  
  90.  
  91. /*      THREAD_STRLEN() is a function that takes the place of the
  92.         standard library routine strlen() which may or may not work
  93.         in a thread.
  94.  
  95.         It requires the following parameters:
  96.                 char *string    a NULL terminated character array.
  97.                                 THREAD_STRLEN() will start at the
  98.                                 beginning of this arrray and count
  99.                                 until it finds a NULL.
  100.  
  101.         It returns the following information:
  102.                 int count       the length of the string.       */
  103. int     thread_strlen( char *string )
  104. {
  105.         int     count;
  106.  
  107.         count = 0;
  108.  
  109.         while( *string )
  110.         {
  111.  
  112.                 string++;
  113.                 count++;
  114.  
  115.         }
  116.  
  117.  
  118.         return( count );
  119.  
  120. }
  121.  
  122.  
  123.  
  124.  
  125.  
  126.  
  127.  
  128. /*  This function will mark any block of memory with the string
  129.     "KevinMcG" over and over again.  The odds against this
  130.     string occurring repeatedly in memory by random chance are
  131.     rather high.  It is an easy string to spot with a debugger.
  132.     If you inspect the stack just before you free it, you will
  133.     be able to spot the high water mark of stack useage and
  134.     adjust your stack allocations accordlingly.             */
  135. void    mark_stack(  char *stack, unsigned length   )
  136. {
  137.         unsigned        full_loops, partial_loop;
  138.  
  139.         full_loops = length / 8;
  140.         partial_loop = length % 8;
  141.  
  142.         /*      Full Loops      */
  143.         for(  ; full_loops > 0; full_loops-- )
  144.         {
  145.                 *stack = 'K';
  146.                 stack++;
  147.  
  148.                 *stack = 'e';
  149.                 stack++;
  150.  
  151.                 *stack = 'v';
  152.                 stack++;
  153.  
  154.                 *stack = 'i';
  155.                 stack++;
  156.  
  157.                 *stack = 'n';
  158.                 stack++;
  159.  
  160.                 *stack = 'M';
  161.                 stack++;
  162.  
  163.                 *stack = 'c';
  164.                 stack++;
  165.  
  166.                 *stack = 'G';
  167.                 stack++;
  168.  
  169.         }
  170.  
  171.         /*      Partial loop to fill in what is left over.      */
  172.         for(   ; partial_loop > 0; partial_loop--  )
  173.         {
  174.                 switch( partial_loop )
  175.                 {
  176.                         case 7:
  177.                                 *stack = 'K';
  178.                                 break;
  179.  
  180.                         case 6:
  181.                                 *stack = 'e';
  182.                                 break;
  183.  
  184.                         case 5:
  185.                                 *stack = 'v';
  186.                                 break;
  187.  
  188.                         case 4:
  189.                                 *stack = 'i';
  190.                                 break;
  191.  
  192.                         case 3:
  193.                                 *stack = 'n';
  194.                                 break;
  195.  
  196.                         case 2:
  197.                                 *stack = 'M';
  198.                                 break;
  199.  
  200.                         case 1:
  201.                                 *stack = 'c';
  202.                                 break;
  203.  
  204.  
  205.                 }
  206.  
  207.                 stack++;
  208.  
  209.         }
  210.  
  211.  
  212. }
  213.  
  214.  
  215.  
  216.  
  217.  
  218. /*      FREE_THE_STACK() is a thread that sleeps until some other thread
  219.         informs it that it is ready to exit.  This thread then waits until
  220.         the other thread's ID becomes invalid and frees the other thread's
  221.         stack segment.          */
  222. PFNTHREAD       free_the_stack( void )
  223. {
  224.         USHORT  error, length, junk;
  225.         HQUEUE  q;
  226.         BYTE    priority;
  227.         QUEUERESULT             info;
  228.         struct stack_selector   *thread;
  229.  
  230.  
  231.  
  232.         error = DosCreateQueue(
  233.                         &q,
  234.                         QUE_FIFO,
  235.                         STACK_KILLER_QUEUE      );
  236.  
  237.  
  238.         /*  If this queue already exists, use it.   */
  239.         if( error == ERROR_QUE_DUPLICATE )
  240.         {
  241.             DosExit( EXIT_THREAD, NO_ERROR );
  242.  
  243.  
  244.         }
  245.  
  246.         /*  Make this a  VERY LOW priority thread.  */
  247.         DosSetPrty( PRTYS_THREAD,
  248.                     PRTYC_IDLETIME,
  249.                     PRTYD_MINIMUM,
  250.                     THIS_THREAD_ONLY    );
  251.  
  252.  
  253.         for(  ;  ;  )
  254.         {
  255.                 /*      Wait for a message.     */
  256.                 error = DosReadQueue(   q,
  257.                                 &info,
  258.                                 &length,
  259.                                 &thread,
  260.                                 NEXT_QUEUE_MESSAGE,
  261.                                 DCWW_WAIT,
  262.                                 &priority,
  263.                                 NO_QUEUE_SEMAPHORE      );
  264.  
  265.                 /*      While the thread ID is still valid...   */
  266.                 do{
  267.                         error = DosGetPrty( PRTYS_THREAD,
  268.                                         &junk,
  269.                                         thread -> id );
  270.  
  271.                         if( error == NO_ERROR )
  272.                         {
  273.                                 /*      Sleep for five seconds. */
  274.                                 error = DosSleep( 5000L );
  275.  
  276.                         }
  277.  
  278.  
  279.                 }while( error == NO_ERROR );
  280.  
  281.                 /*      Free the stack segment. */
  282.                 DosFreeSeg( thread -> stack );
  283.  
  284.                 /*      Free the message data area.     */
  285.                 DosFreeSeg(   SELECTOROF(thread)   );
  286.  
  287.  
  288.         }
  289.  
  290.  
  291. }
  292.