home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Network Support Encyclopedia 96-1
/
novell-nsepro-1996-1-cd2.iso
/
download
/
netware
/
xnut2.exe
/
NWSTHRD.C
next >
Wrap
Text File
|
1994-09-09
|
15KB
|
495 lines
/**************************************************************************
** File: nwsthrd.c
**
** Desc: Example of using multi-threaded programs with NWSNUT
**
** Disclaimer:
**
** Novell, Inc. makes no representations or warranties with respect to
** any NetWare software, and specifically disclaims any express or
** implied warranties of merchantability, title, or fitness for a
** particular purpose.
**
** Distribution of any NetWare software is forbidden without the
** express written consent of Novell, Inc. Further, Novell reserves
** the right to discontinue distribution of any NetWare software.
**
** Novell is not responsible for lost profits or revenue, loss of use
** of the software, loss of data, costs of re-creating lost data, the
** cost of any substitute equipment or program, or claims by any party
** other than you. Novell strongly recommends a backup be made before
** any software is installed. Technical support for this software
** may be provided at the discretion of Novell.
**
**
** QMK386 options used:
**
** /in Include import statement for NWSNUT symbols.
** /z Generate NLMLINKx version of def file.
** /ohNWSTHRD.HLP Help file.
** /omNWSTHRD.MSG Message file.
**
** Programmers:
**
** Ini Who Firm
** ---------------------------------------------------------------------
** DWH Dirk W. Howard Novell Developer Support
**
**
** History:
**
** When Who What
** ---------------------------------------------------------------------
** 8-31-1994 DWH First code.
**
*/
/**************************************************************************
** Include files and macro definitions
*/
/*----------------------------------------------------------------------
** ANSI Includes
*/
#include <stdlib.h> /* NULL */
#include <stdio.h> /* sprintf(), printf() */
#include <string.h> /* strlen() */
#include <conio.h> /* GetCurrentScreen(), SetAutoScreenDestructionMode() */
#include <signal.h> /* signal(), SIGTERM */
/*----------------------------------------------------------------------
** NetWare Includes
*/
#include <process.h> /* delay(), ThreadSwitchWithDelay(), GetNLMHandle(), BeginThread() */
#include <errno.h> /* errno, ENO_SCRNS, EFAILURE, ENOMEM, EINVAL */
#include <nwsnut.h> /* Enough said? */
#include <advanced.h>/* AllocateResourceTag(), AllocSignature */
/*----------------------------------------------------------------------
** NWSTHRD
*/
#include "nwsthrd.mlh"
#include "nwsthrd.hlh"
#define FlagSet(arg1, arg2) ((arg1) & (arg2))
#define PORTAL_TEXT_WIDTH 38
/**************************************************************************
** Global variables
*/
int NLM_shutdown = FALSE;
int NLM_noUpdate = FALSE;
int NLM_threadCount = 0;
NUTInfo *NLM_nutHandle;
PCB *NLM_pPcb;
/**************************************************************************
** Generic Thread
*/
void genericThread(void *arg)
{
LONG count = 0;
LONG threadNo = (LONG)arg;
char message[128];
LONG delayAmount = 1000 * threadNo;
NLM_threadCount++;
while(TRUE)
{
if(NLM_shutdown)
{
sprintf(message, "Closing thread %d", threadNo);
NWSShowPortalLine(
/* I- line */ threadNo,
/* I- column */ 0,
/* I- text */ message,
/* I- length */ PORTAL_TEXT_WIDTH,
/* I- portal */ NLM_pPcb
);
if(!NLM_nutHandle->helpActive && !NLM_nutHandle->errorDisplayActive)
NWSUpdatePortal(NLM_pPcb);
NLM_threadCount--;
return;
}
count++;
if((count % 10) && (NLM_noUpdate == FALSE))
{
sprintf( message, "Spinning in thread %d %04d", threadNo, count );
NWSShowPortalLine(
/* I- line */ threadNo,
/* I- column */ 0,
/* I- text */ message,
/* I- length */ PORTAL_TEXT_WIDTH,
/* I- portal */ NLM_pPcb
);
if(!NLM_nutHandle->helpActive && !NLM_nutHandle->errorDisplayActive)
NWSUpdatePortal(NLM_pPcb);
}
delay(delayAmount);
}
}
/**************************************************************************
** AddToList Insert Procedure
*/
int AddToList(BYTE *text, void **otherInfo, void *parameters)
{
int ccode;
otherInfo = otherInfo;
parameters = parameters;
ccode = NWSEditString(
/* I- centerLine */ 16,
/* I- centerColumn */ 40,
/* I- editHeight */ 1,
/* I- editWidth */ PORTAL_TEXT_WIDTH,
/* I- header */ INSERT_HEADER,
/* I- prompt */ INSERT_PROMPT,
/* I- buf */ text,
/* I- maxLen */ PORTAL_TEXT_WIDTH,
/* I- type */ EF_ANY,
/* I- handle */ NLM_nutHandle,
/* I- insertProcedure */ NULL,
/* I- actionProcedure */ NULL,
/* I- parameters */ NULL
);
if(FlagSet(ccode, E_ESCAPE|E_EMPTY)) return(1);
return(0);
}
/**************************************************************************
** ModifyElement Procedure
*/
int ModifyElement(BYTE *text, void *parameters)
{
int ccode;
parameters = parameters;
ccode = NWSEditString(
/* I- centerLine */ 16,
/* I- centerColumn */ 40,
/* I- editHeight */ 1,
/* I- editWidth */ PORTAL_TEXT_WIDTH,
/* I- header */ INSERT_HEADER,
/* I- prompt */ INSERT_PROMPT,
/* I- buf */ text,
/* I- maxLen */ PORTAL_TEXT_WIDTH,
/* I- type */ EF_ANY,
/* I- handle */ NLM_nutHandle,
/* I- insertProcedure */ NULL,
/* I- actionProcedure */ NULL,
/* I- parameters */ NULL
);
if(FlagSet(ccode, E_ESCAPE|E_EMPTY)) return(1);
if(FlagSet( ccode, E_CHANGE )) return(0);
return(1);
}
/**************************************************************************
** ListAction Procedure
*/
int ListAction(LONG keyPressed, LIST **elementSelected, LONG *itemNumber, void *listParameter)
{
char message[128];
listParameter = listParameter;
itemNumber = itemNumber;
switch (keyPressed)
{
case M_ESCAPE:
return(1);
case M_SELECT:
NWSShowPortalLine(
/* I- line */ 0,
/* I- column */ 0,
/* I- text */ "",
/* I- length */ PORTAL_TEXT_WIDTH,
/* I- portal */ NLM_pPcb
);
if(!NLM_nutHandle->helpActive && !NLM_nutHandle->errorDisplayActive)
NWSUpdatePortal(NLM_pPcb);
sprintf(message, "You selected : \"%s\"", (char *)((*elementSelected)->text));
NWSShowPortalLine(
/* I- line */ 0,
/* I- column */ 0,
/* I- text */ message,
/* I- length */ strlen(message),
/* I- portal */ NLM_pPcb
);
if(!NLM_nutHandle->helpActive && !NLM_nutHandle->errorDisplayActive)
NWSUpdatePortal(NLM_pPcb);
return(-1);
case M_INSERT:
NWSPushHelpContext(INSERT_HLP, NLM_nutHandle);
NWSInsertInPortalList(
/* I- currentElement */ elementSelected,
/* I- currentLine */ itemNumber,
/* I- insertProcedure */ AddToList,
/* I- FreeProcedure */ free,
/* I- handle */ NLM_nutHandle,
/* I- parameters */ NULL
);
NWSPopHelpContext(NLM_nutHandle);
return(-1);
case M_DELETE:
case M_MDELETE:
NWSPushHelpContext(DELETE_HLP, NLM_nutHandle);
NLM_noUpdate = TRUE;
NWSDeleteFromPortalList(
/* I- currentElement */ elementSelected,
/* I- currentLine */ itemNumber,
/* I- deleteProcedure */ NULL,
/* I- deleteCurrentMessageID */ DELETE_CURRENT,
/* I- deleteMarkedMessageID */ DELETE_MARKED,
/* I- handle */ NLM_nutHandle,
/* I- parameters */ NULL
);
NLM_noUpdate = FALSE;
NWSPopHelpContext(NLM_nutHandle);
return(-1);
case M_MODIFY:
NWSPushHelpContext(MODIFY_HLP, NLM_nutHandle);
NWSModifyInPortalList(
/* I- currentElement */ elementSelected,
/* I- currentLine */ itemNumber,
/* I- ModifyProcedure */ ModifyElement,
/* I- handle */ NLM_nutHandle,
/* I- parameters */ NULL
);
NWSPopHelpContext(NLM_nutHandle);
return(-1);
default:
NWSShowPortalLine(
/* I- line */ 0,
/* I- column */ 0,
/* I- text */ "",
/* I- length */ PORTAL_TEXT_WIDTH,
/* I- portal */ NLM_pPcb
);
if(!NLM_nutHandle->helpActive && !NLM_nutHandle->errorDisplayActive)
NWSUpdatePortal(NLM_pPcb);
return(-1);
}
}
/**************************************************************************
** WeWereUnloaded Procedure
*/
void WeWereUnloaded(int sigtype)
{
sigtype = sigtype;
NLM_shutdown = TRUE;
while(NLM_threadCount > 0)
ThreadSwitchWithDelay();
NWSRestoreNut(NLM_nutHandle);
}
/**************************************************************************
** main procedure
*/
void main(void)
{
LONG nlmHandle;
LONG nutAllocTag;
int cCode;
LONG lCode;
BYTE bCode;
LONG threadPortal;
LONG portalTop = 4; /* position at 1, 1 on physical screen */
LONG portalLeft = 1;
LONG portalFrameHeight = 8; /* make the portal 8 X 40 */
LONG portalFrameWidth = 40;
LONG portalVirtualHeight = 4;/* make the virtual portal 4 X PORTAL_TEXT_WIDTH */
LONG portalVirtualWidth = PORTAL_TEXT_WIDTH;
LONG threadCnt;
LIST *node;
/*------------------------------------------------------------------------
** Set-up
*/
nlmHandle = GetNLMHandle();
bCode=SetAutoScreenDestructionMode(TRUE);
if(bCode == -1) switch(errno)
{
case ENO_SCRNS:
printf("ERROR: SetAutoScreenDestructionMode() reports \"No Screens\".\n");
goto END;
default:
printf("ERROR: SetAutoScreenDestructionMode() reports unknown error: %d.\n", errno);
goto END;
}
signal(SIGTERM, WeWereUnloaded);
nutAllocTag = AllocateResourceTag(
/* I- NLMHandle */ nlmHandle,
/* I- descriptionString */ "NWSThrd_NUT",
/* I- resoruceType */ AllocSignature
);
if(!nutAllocTag)
{
printf("ERROR: AllocResoruceTag() failed.\n");
goto END;
}
lCode = NWSInitializeNut(
/* I- Utility */ NAME,
/* I- version */ VERSION,
/* I- headerType */ NORMAL_HEADER,
/* I- compatibilityType */ 0,
/* I- messageTable */ NULL,
/* I- helpScreens */ NULL,
/* I- screenID */ GetCurrentScreen(),
/* I- resourceTag */ nutAllocTag,
/* -O handle */ &NLM_nutHandle
);
switch(lCode)
{
case 0:
break;
default:
printf("ERROR: NWSInitializeNut() failed. [%d]\n", lCode);
goto END;
}
NWSDisplayPreHelp(
/* I- line */ 22,
/* I- column */ 40,
/* I- message */ PREHELP_MSG,
/* I handle */ NLM_nutHandle
);
NWSPushHelpContext(MAIN_HLP, NLM_nutHandle);
threadPortal = NWSCreatePortal(
/* I- line */ portalTop,
/* I- column */ portalLeft,
/* I- frameHeight */ portalFrameHeight,
/* I- frameWidth */ portalFrameWidth,
/* I- virtualHeight */ portalVirtualHeight,
/* I- virtualWidth */ portalVirtualWidth,
/* I- saveFlag */ SAVE,
/* I- headerText */ "Thread Portal",
/* I- headerAttribute */ 0,
/* I- borderType */ DOUBLE,
/* I- borderAttribute */ 0,
/* I- cursorFlag */ CURSOR_ON,
/* I- directFlag */ VIRTUAL,
/* I- handle */ NLM_nutHandle
);
switch(threadPortal)
{
case 0xFFFFFFFEL:
NWSTrace(NLM_nutHandle, "ERROR: NWSCreatePortal() indicated: \"Out of memory\"");
goto END;
case 0xFFFFFFFFL:
NWSTrace(NLM_nutHandle, "ERROR: NWSCreatePortal() indicated: \"Max number of portals already defined.\"");
goto END;
/*---------------------------------------------------------------------
** If not one of the above documented values, value is an address.
*/
default:
break;
}
NWSGetPCB(
/* -O pPcb */ &NLM_pPcb,
/* I- portalNumber */ threadPortal,
/* I- handle */ NLM_nutHandle
);
/*------------------------------------------------------------------------
** Build, display and interact with list.
*/
for(threadCnt = 1L; threadCnt <= 3; ++threadCnt)
{
cCode=BeginThread(
/* I- funct */ genericThread,
/* I- stack */ NULL,
/* I- stackSize */ 0,
/* I- arg */ (void *)threadCnt
);
if(cCode == EFAILURE) switch(errno)
{
case ENOMEM:
NWSTrace(NLM_nutHandle, "ERROR: BeginThread() indicated \"Not enough memory\"\n");
goto END;
case EINVAL:
NWSTrace(NLM_nutHandle, "ERROR: BeginThread() indicated \"Invalid arg was passed in.\"\n");
goto END;
default:
NWSTrace(NLM_nutHandle, "ERROR: BeginThread() returned unknown error: %d.\n", cCode);
goto END;
}
}
NWSInitList(
/* I- handle */ NLM_nutHandle,
/* i- freeRoutine */ free
);
node=NWSAppendToList("Test Item", NULL, NLM_nutHandle);
if(node == NULL) NWSTrace(NLM_nutHandle, "ERROR: NWSAppendToList(#1) failed.\n");
NWSAppendToList("Another Test Item", NULL, NLM_nutHandle);
if(node == NULL) NWSTrace(NLM_nutHandle, "ERROR: NWSAppendToList(#2) failed.\n");
NWSList(
/* header */ LIST_HEADER,
/* centerLine */ 4,
/* centerColumn */ 55,
/* height */ 4,
/* width */ strlen(NWSGetMessage(LIST_HEADER, &(NLM_nutHandle->messages))) +4,
/* validKeyFlags */ M_ESCAPE|M_SELECT|M_INSERT|M_DELETE|M_MDELETE|M_MODIFY,
/* element */ NULL,
/* handle */ NLM_nutHandle,
/* formatProcedure */ NULL,
/* actionProcedure */ ListAction,
/* actionParameter */ NULL
);
/*------------------------------------------------------------------------
** close down
*/
NLM_shutdown = TRUE;
while(NLM_threadCount > 0) ThreadSwitchWithDelay();
delay(1000);
NWSDestroyPortal(
/* portalNumber */ threadPortal,
/* handle */ NLM_nutHandle
);
NWSRestoreNut(NLM_nutHandle);
END:
return;
}