home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: WPS_PM
/
WPS_PM.zip
/
xfld085s.zip
/
helpers
/
threads.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-02-23
|
7KB
|
235 lines
/*
*@@sourcefile threads.c:
* contains helper functions for creating, destroying, and
* synchronizing threads.
*
* Function prefixes (new with V0.81):
* -- thr* Thread helper functions
*
* This file is new with V0.81 and contains all the thread
* functions that used to be in helpers.c.
*
*@@include #define INCL_DOSPROCESS
*@@include #include <os2.h>
*@@include #include "threads.h"
*/
/*
* Copyright (C) 1997-99 Ulrich Möller.
* This file is part of the XFolder source package.
* XFolder is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, in version 2 as it comes in the
* "COPYING" file of the XFolder main distribution.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#define INCL_DOSPROCESS
#define INCL_DOSERRORS
#include <os2.h>
#include <stdlib.h>
#include "threads.h"
/*
*@@ thrCreate:
* this function creates a THREADINFO structure in *ppti;
* you must pass the thread function in pfn, which will
* then be executed. The thread will be passed a pointer
* to the new THREADINFO structure as its thread parameter.
* The ulData field in that structure is set to ulData
* here. Use whatever you like.
* Note: As opposed to previous versions, V0.84 now expects
* *pfn to have _Optlink calling convention, because now
* _beginthread() is used instead of DosCreateThread().
*/
BOOL thrCreate(PTHREADINFO *ppti, // out: where to create THREADINFO
PTHREADFUNC pfn, // in: _Optlink thread function
ULONG ulData) // in: user data to be stored in THREADINFO
{
BOOL rc = FALSE;
PTHREADINFO pti = NULL;
if (ppti)
{
if (*ppti == NULL)
pti = (PTHREADINFO)malloc(sizeof(THREADINFO));
else
if ((*ppti)->tid == NULLHANDLE)
pti = *ppti;
if (pti) {
// we arrive here if *ppti was NULL or (*ppti->tid == NULLHANDLE),
// i.e. the thread is not already running. We use
// DosCreateThread and not _beginthread because we
// do not use the compiler's default exception handlers,
// but our own ones for each thread we create, so there.
// _beginthread is contained both in the VAC++ and EMX
// C libraries with this syntax.
pti->tid = _beginthread(
pfn,
0, // unused compatibility param
65536, // stack size
pti); // parameter passed to thread
pti->cb = sizeof(THREADINFO);
pti->ulData = ulData;
pti->fExit = FALSE;
pti->hab = NULLHANDLE;
pti->fExitComplete = FALSE;
pti->ulResult = 0;
pti->ulFuncInfo = 0;
rc = TRUE;
}
*ppti = pti;
}
return (rc);
}
/*
*@@ thrClose:
* this functions sets the "fExit" flag in
* THREADINFO to TRUE;
* the thread should monitor this flag
* periodically and then terminate itself.
*/
BOOL thrClose(PTHREADINFO pti)
{
if (pti) {
pti->fExit = TRUE;
return (TRUE);
}
return (FALSE);
}
/*
*@@ thrGoodbye:
* every thread should call this function just before
* it terminates itself so that the other thread funcs
* can react properly. This updates the THREADINFO
* structure, but does _not_ call _endthread(). So you
* should either call this function before calling
* _endthread() or as the last function call in the
* thread function itself before it exits.
*/
VOID thrGoodbye(PTHREADINFO pti)
{
if (pti) {
pti->fExitComplete = TRUE;
pti->tid = NULLHANDLE;
}
}
/*
*@@ thrWait:
* this function waits for a thread to end by calling
* DosWaitThread. Note that this blocks the calling
* thread, so only use this function when you're sure
* the thread will actually terminate.
*/
BOOL thrWait(PTHREADINFO pti)
{
if (pti) {
DosWaitThread(&(pti->tid), DCWW_WAIT);
pti->tid = NULLHANDLE;
return (TRUE);
}
return (FALSE);
}
/*
*@@ thrFree:
* this is a combination of thrClose and
* thrWait; the THREADINFO block is then freed
* and *ppti set to NULL.
*/
BOOL thrFree(PTHREADINFO *ppti)
{
if (ppti)
if (*ppti) {
if ((*ppti)->tid) {
thrClose(*ppti);
thrWait(*ppti);
}
free(*ppti);
*ppti = NULL;
return (TRUE);
}
return (FALSE);
}
/*
*@@ thrKill:
* just like thrFree, but the thread is
* brutally killed, using DosKillThread.
*/
BOOL thrKill(PTHREADINFO *ppti)
{
if (ppti)
if (*ppti) {
if ((*ppti)->tid) {
DosResumeThread((*ppti)->tid);
// this returns an error if the thread
// is not suspended, but otherwise the
// system might hang
DosKillThread((*ppti)->tid);
}
free(*ppti);
*ppti = NULL;
return (TRUE);
}
return (FALSE);
}
/*
*@@ thrQueryID:
* returns thread ID.
*/
TID thrQueryID(PTHREADINFO pti)
{
if (pti)
if (!(pti->fExitComplete))
return (pti->tid);
return NULLHANDLE;
}
/*
*@@ thrQueryPriority:
* returns the priority of the calling thread.
* The low byte of the low word is a hexadecimal value
* representing a rank (value 0 to 31) within a priority class.
* Class values, found in the high byte of the low word, are
* as follows:
* 0x01 idle
* 0x02 regular
* 0x03 time-critical
* 0x04 server
*/
ULONG thrQueryPriority(VOID)
{
PTIB ptib;
PPIB ppib;
if (DosGetInfoBlocks(&ptib, &ppib) == NO_ERROR)
if (ptib)
if (ptib->tib_ptib2)
return (ptib->tib_ptib2->tib2_ulpri);
return (0);
}