home *** CD-ROM | disk | FTP | other *** search
- /**************************************************************************
- * File name : thrd.c
- *
- * Description: This module contains the code for a background processing
- * thread as well as the code for any routines used in that
- * thread.
- *
- * This thread uses an object window to facilitate
- * communication with the main thread. The main thread can
- * communicate with the background thread through messages.
- * You define your own window messages in main.h, post or send
- * them to the background thread through the routines provided
- * in this file, and then process the messages in the
- * ObjectWndProc() routine. The object window then sends
- * other messages back to the main window to notify the main
- * window as to the status of the task or with the final
- * result.
- *
- * An object window is used as the main window of the thread
- * for several reasons. The window is hidden, so it is
- * never displayed on the screen. Since it is hidden, the
- * window does not have to process most of the window
- * messages that are processed by visible windows, e.g.
- * WM_PAINT, WM_SIZE, WM_SETFOCUS, etc. This window will
- * never receive the focus so it need not process input
- * messages. You can, however, send all mouse and keyboard
- * messages to this window and have it process all input if
- * you wish. Since the window does not belong to any focus
- * or activation chains, you can block this thread on a
- * semaphore without having the system lock up or use the
- * window manager semaphore routines such as
- * WinMsgSemWait().
- *
- * The BackgroundThread() routine is designed to create only
- * one thread. Should you try to create another one, the
- * call will fail. The thread uses several variables
- * which are defined globally within this module. In order
- * to enable this routine to create multiple threads, you
- * will need to make these variables local. You will also
- * need to differentiate between the different object
- * windows created so that you can specify which thread will
- * receive a posted message.
- *
- * In order to enable the use of the second thread, define
- * the BACKGROUND_THREAD constant found in main.h.
- *
- * This source file contains the following functions:
- *
- * BackgroundThread()
- * CreateBackgroundThread()
- * DestroyBackgroundThread()
- * PostBkThreadMsg(msg, mp1, mp2)
- * SendBkThreadMsg(msg, mp1, mp2)
- * ObjectWndProc(hwnd, msg, mp1, mp2)
- *
- * Concepts : background thread
- *
- * API's : WinInitialize
- * WinPostMsg
- * DosExit
- * WinCreateMsgQueue
- * WinTerminate
- * WinLoadString
- * WinRegisterClass
- * WinCreateWindow
- * DosPostEventSem
- * WinGetMsg
- * WinDispatchMsg
- * WinIsWindow
- * WinDestroyWindow
- * WinDestroyMsgQueue
- * DosCreateEventSem
- * DosCreateThread
- * WinWaitEventSem
- * DosWaitThread
- * WinDefWindowProc
- *
- * Required
- * Files : OS2.H, MAIN.H, XTRN.H
- *
- * Copyright (C) 1991 IBM Corporation
- *
- * DISCLAIMER OF WARRANTIES. The following [enclosed] code is
- * sample code created by IBM Corporation. This sample code is not
- * part of any standard or IBM product and is provided to you solely
- * for the purpose of assisting you in the development of your
- * applications. The code is provided "AS IS", without
- * warranty of any kind. IBM shall not be liable for any damages
- * arising out of your use of the sample code, even if they have been
- * advised of the possibility of such damages. *
- *************************************************************************/
- /*
- * Include files, macros, defined constants, and externs
- */
-
- #define INCL_DOSPROCESS
- #define INCL_DOSSEMAPHORES
-
- #include <os2.h>
- #include "main.h"
- #include "xtrn.h"
-
- #define THREADSTACKSIZE 8192L
- #define SEM_TIMEOUT 10000L
-
- /*
- * Global variables
- */
- static HAB habBkThread;
- static HMQ hmqBkThread;
- static TID tidBkThread;
- static HWND hwndObject;
- static CHAR szObjectClass[MAXNAMEL];
- static BOOL fThreadCreated = FALSE;
- static HEV hevThreadInit; /* semaphore for thread initialization */
-
- VOID BackgroundThread (ULONG);
-
- MRESULT EXPENTRY ObjectWndProc(HWND, ULONG, MPARAM, MPARAM);
-
- /**************************************************************************
- *
- * Name : BackgroundThread(ulThreadParam)
- *
- * Description: Routine is a background thread used for tasks to be
- * completed in the background.
- *
- * Concepts: Routine is called at initialization time to create
- * a background processing thread.
- *
- * The routine initializes itself as a PM thread and creates
- * a message queue. It then creates an object window
- * through which it will receive and send messages.
- * It then polls through a message loop, processing any
- * messages it receives in the object window's window
- * procedure. When the loop ends, it terminates.
- *
- * API's : WinInitialize
- * WinPostMsg
- * DosExit
- * WinCreateMsgQueue
- * WinLoadString
- * WinRegisterClass
- * WinCreateWindow
- * DosPostEventSem
- * WinGetMsg
- * WinDispatchMsg
- * WinIsWindow
- * WinDestroyWindow
- * WinDestroyMsgQueue
- *
- * Parameters : ulThreadParam = thread parameter
- *
- * Return : [none]
- *
- *************************************************************************/
- VOID BackgroundThread(ULONG ulThreadParam)
- {
- QMSG qmsg;
-
- /* create message queue for thread */
- habBkThread = WinInitialize(0);
- if(habBkThread == NULLHANDLE)
- {
- WinPostMsg(hwndMain, TM_THREADINITFAILED, (MPARAM)NULL, (MPARAM)NULL);
- DosExit(EXIT_THREAD, 0L);
- }
-
- hmqBkThread = WinCreateMsgQueue(habBkThread, 0);
- if(hmqBkThread == NULLHANDLE)
- {
- WinPostMsg(hwndMain, TM_THREADINITFAILED, (MPARAM)NULL, (MPARAM)NULL);
-
- WinTerminate(habBkThread);
- DosExit(EXIT_THREAD, 0L);
- }
-
- /* load the string for the object window class and register the class */
- if(WinLoadString(habBkThread,
- (HMODULE)NULLHANDLE,
- IDS_OBJECTCLASS,
- MAXNAMEL,
- (PSZ)szObjectClass)
- &&
- /* register the main client window class */
- WinRegisterClass(habBkThread,
- (PSZ)szObjectClass,
- (PFNWP)ObjectWndProc,
- 0L,
- 0L)
- &&
- /* create the object window */
- (NULLHANDLE != (hwndObject = WinCreateWindow(HWND_OBJECT,
- (PSZ)szObjectClass,
- (PSZ)NULL,
- 0L,
- 0L,
- 0L,
- 0L,
- 0L,
- (HWND)NULLHANDLE,
- HWND_TOP,
- OBJECTID,
- (PVOID)NULL,
- (PVOID)NULL))))
- {
- /* set thread created flag so another thread of this type
- * cannot be created.
- */
- fThreadCreated = TRUE;
-
- /* clear initialization semaphore */
- DosPostEventSem(hevThreadInit);
-
- /* message loop */
- while(WinGetMsg(habBkThread, &qmsg, (HWND)NULLHANDLE, 0L, 0L))
- WinDispatchMsg(habBkThread, &qmsg);
- }
- else
- {
- WinPostMsg(hwndMain, TM_THREADINITFAILED, NULL, NULL);
- }
-
- /* destroy object window, clean up message queue and terminate */
- if(WinIsWindow(habBkThread, hwndObject))
- WinDestroyWindow(hwndObject);
-
- WinDestroyMsgQueue(hmqBkThread);
- WinTerminate(habBkThread);
-
- /* If termination is due to an error initializing the thread, then
- clear the initialization semaphore so that the main thread
- can continue. */
- if(!fThreadCreated)
- DosPostEventSem(hevThreadInit);
-
- DosExit(EXIT_THREAD, 0L);
-
- /* the thread parameter is not currently used */
- ulThreadParam;
- } /* End of BackgroundThread */
-
-
- /**************************************************************************
- *
- * Name : CreateBackgroundThread()
- *
- * Description: Creates the background thread
- *
- * Concepts: Routine is called at initialization time to create
- * a background processing thread.
- *
- * The routine calls DosCreateThread with the Background
- * thread routine.
- *
- * API's : DosCreateEventSem
- * DosCreateThread
- * WinWaitEventSem
- *
- * Parameters : [none]
- *
- * Return : TRUE = thread is created successfully
- * FALSE = not, or if the thread was already created
- *
- *************************************************************************/
- BOOL CreateBackgroundThread(VOID)
- {
- ULONG sRet;
-
- if(!fThreadCreated)
- {
- DosCreateEventSem((PSZ)NULL, &hevThreadInit, 0L, FALSE);
- sRet = (ULONG)DosCreateThread(&tidBkThread,
- (PFNTHREAD)BackgroundThread,
- 0L,
- 0L,
- THREADSTACKSIZE);
- }
- else
- return FALSE;
-
- /* wait until the thread has finished initialization */
- if(WinWaitEventSem(hevThreadInit, SEM_TIMEOUT))
- return FALSE;
-
- return((BOOL)(sRet == 0L));
- } /* End of CreateBackgroundThread */
-
- /**************************************************************************
- *
- * Name : DestroyBackgroundThread()
- *
- * Description: Destroys the background thread
- *
- * Concepts: Routine is called at exit time to destroy the
- * background processing thread.
- *
- * The routine posts a WM_CLOSE message to the object window
- * to end its message loop. It then waits to make sure that
- * the thread has been terminated before it returns.
- *
- * API's : DosWaitThread
- *
- * Parameters : [none]
- *
- * Return : [none]
- *
- *************************************************************************/
- VOID DestroyBackgroundThread(VOID)
- {
- PostBkThreadMsg(WM_CLOSE, (MPARAM)NULL, (MPARAM)NULL);
- DosWaitThread(&tidBkThread, 0L);
- } /* End of DestroyBackgroundThread */
-
-
- /**************************************************************************
- *
- * Name : PostBkThreadMsg(msg, mp1, mp2)
- *
- * Description: Routine posts a message to the object window of the
- * background thread.
- *
- * Concepts: Routine is called whenever a message is to be posted to
- * the background processing thread.
- *
- * The routine posts the message to the object window of the
- * thread.
- *
- * API's : WinPostMsg
- *
- * Parameters : msg = the message i.d.
- * mp1 = first message parameter
- * mp2 = second message parameter
- *
- * Return : the return value from WinPostMsg().
- *
- *************************************************************************/
- BOOL PostBkThreadMsg(ULONG msg, MPARAM mp1, MPARAM mp2)
- {
- return(WinPostMsg(hwndObject, msg, mp1, mp2));
- } /* End of PostBkThreadMsg */
-
-
- /**************************************************************************
- *
- * Name : SendBkThreadMsg(msg, mp1, mp2)
- *
- * Description: Routine sends a message to the object window of the
- * background thread.
- *
- * Concepts: Routine is called whenever a message is to be sent to
- * the background processing thread.
- *
- * The routine sends the message to the object window of the
- * thread.
- *
- * API's : WinSendMsg
- *
- * Parameters : msg = the message i.d.
- * mp1 = first message parameter
- * mp2 = second message parameter
- *
- * Return : the return value from WinSendMsg().
- *
- *************************************************************************/
- MRESULT SendBkThreadMsg(ULONG msg, MPARAM mp1, MPARAM mp2)
- {
- return(WinSendMsg(hwndObject, msg, mp1, mp2));
- } /* End of SendBkThreadMsg */
-
-
-
- /**************************************************************************
- *
- * Name : ObjectWndProc(hwnd, msg, mp1, mp2)
- *
- * Description: Processes all messages sent to the Object window
- *
- * Concepts: Called for each message sent to the Object window.
- *
- * The Object window processes the messages that tell
- * the background thread what action to take. Since
- * the object window is not visible, it will not
- * process any of the standard window messages.
- *
- * API's : WinDefWindowProc
- *
- * Parameters : hwnd= window handle
- * msg = the message i.d.
- * mp1 = first message parameter
- * mp2 = second message parameter
- *
- * Return : dependent on message sent
- *
- *************************************************************************/
- MRESULT EXPENTRY ObjectWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
- {
- switch(msg)
- {
- /*
- * Include any user-defined messages to determine which
- * action the background thread should take.
- */
-
- default:
- return (WinDefWindowProc(hwnd, msg, mp1, mp2));
- break;
- }
- return (MRESULT)NULL;
- } /* End of ObjectWndProc */
- /*************************** End of thrd.c ****************************/
-