home *** CD-ROM | disk | FTP | other *** search
- /*
-
-
-
- THREAD.c
-
-
- Copyright (c) 1990 by: Arthur Kevin McGrath
- P. O. Box 128
- Barboursville, VA 22923
-
- 703/832-7025
-
-
- ALL RIGHTS ARE RESERVED. You may not copy this program in any way
- except to make back-up copies FOR YOUR OWN USE. If you copy this
- program for any reason without WRITTEN PERMISSION from the above
- named copyright owner (except to make back-up copies FOR YOUR OWN USE),
- you are breaking the Copyright Laws of the United States. You will go
- to jail for one year and pay a 50,000 fine.
-
-
-
-
- */
-
-
- #include <stdio.h>
-
- #define INCL_WIN
- #define INCL_GPI
- #define INCL_BASE
- #include <os2.h>
-
- #include "capture.h"
-
-
- /* THREAD_COPY() is a function that takes the place of the
- standard library function strcpy() which does not always
- work in a thread.
-
- It requires the following parameters:
- char *destination where will everything be
- copied TO
- char *source where will everything be
- copied FROM */
- void thread_copy( char *destination, char *source )
- {
- while( *source )
- {
- *destination = *source;
- destination++;
- source++;
-
- }
-
- /* Terminate the destination string. */
- *destination = '\0';
-
- }
-
-
-
-
- /* THREAD_CAT() is a function that takes the place of the
- standard library routine strcat() which does not always
- work when called from a thread.
-
- This routine requires the following parameters:
- char *destination where will everything be
- concatenated TO
- char *source what will be added to the
- end of the destination string. */
- void thread_cat( char *destination, char *source )
- {
- /* Get to the end of the destination string. */
- while( *destination )
- {
- destination++;
-
- }
-
- /* Copy the new stuff to the end of the destination. */
- thread_copy( destination, source );
-
- }
-
-
-
-
- /* THREAD_STRLEN() is a function that takes the place of the
- standard library routine strlen() which may or may not work
- in a thread.
-
- It requires the following parameters:
- char *string a NULL terminated character array.
- THREAD_STRLEN() will start at the
- beginning of this arrray and count
- until it finds a NULL.
-
- It returns the following information:
- int count the length of the string. */
- int thread_strlen( char *string )
- {
- int count;
-
- count = 0;
-
- while( *string )
- {
-
- string++;
- count++;
-
- }
-
-
- return( count );
-
- }
-
-
-
-
-
-
-
- /* This function will mark any block of memory with the string
- "KevinMcG" over and over again. The odds against this
- string occurring repeatedly in memory by random chance are
- rather high. It is an easy string to spot with a debugger.
- If you inspect the stack just before you free it, you will
- be able to spot the high water mark of stack useage and
- adjust your stack allocations accordlingly. */
- void mark_stack( char *stack, unsigned length )
- {
- unsigned full_loops, partial_loop;
-
- full_loops = length / 8;
- partial_loop = length % 8;
-
- /* Full Loops */
- for( ; full_loops > 0; full_loops-- )
- {
- *stack = 'K';
- stack++;
-
- *stack = 'e';
- stack++;
-
- *stack = 'v';
- stack++;
-
- *stack = 'i';
- stack++;
-
- *stack = 'n';
- stack++;
-
- *stack = 'M';
- stack++;
-
- *stack = 'c';
- stack++;
-
- *stack = 'G';
- stack++;
-
- }
-
- /* Partial loop to fill in what is left over. */
- for( ; partial_loop > 0; partial_loop-- )
- {
- switch( partial_loop )
- {
- case 7:
- *stack = 'K';
- break;
-
- case 6:
- *stack = 'e';
- break;
-
- case 5:
- *stack = 'v';
- break;
-
- case 4:
- *stack = 'i';
- break;
-
- case 3:
- *stack = 'n';
- break;
-
- case 2:
- *stack = 'M';
- break;
-
- case 1:
- *stack = 'c';
- break;
-
-
- }
-
- stack++;
-
- }
-
-
- }
-
-
-
-
-
- /* FREE_THE_STACK() is a thread that sleeps until some other thread
- informs it that it is ready to exit. This thread then waits until
- the other thread's ID becomes invalid and frees the other thread's
- stack segment. */
- PFNTHREAD free_the_stack( void )
- {
- USHORT error, length, junk;
- HQUEUE q;
- BYTE priority;
- QUEUERESULT info;
- struct stack_selector *thread;
-
-
-
- error = DosCreateQueue(
- &q,
- QUE_FIFO,
- STACK_KILLER_QUEUE );
-
-
- /* If this queue already exists, use it. */
- if( error == ERROR_QUE_DUPLICATE )
- {
- DosExit( EXIT_THREAD, NO_ERROR );
-
-
- }
-
- /* Make this a VERY LOW priority thread. */
- DosSetPrty( PRTYS_THREAD,
- PRTYC_IDLETIME,
- PRTYD_MINIMUM,
- THIS_THREAD_ONLY );
-
-
- for( ; ; )
- {
- /* Wait for a message. */
- error = DosReadQueue( q,
- &info,
- &length,
- &thread,
- NEXT_QUEUE_MESSAGE,
- DCWW_WAIT,
- &priority,
- NO_QUEUE_SEMAPHORE );
-
- /* While the thread ID is still valid... */
- do{
- error = DosGetPrty( PRTYS_THREAD,
- &junk,
- thread -> id );
-
- if( error == NO_ERROR )
- {
- /* Sleep for five seconds. */
- error = DosSleep( 5000L );
-
- }
-
-
- }while( error == NO_ERROR );
-
- /* Free the stack segment. */
- DosFreeSeg( thread -> stack );
-
- /* Free the message data area. */
- DosFreeSeg( SELECTOROF(thread) );
-
-
- }
-
-
- }