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 >
Text File  |  1994-09-09  |  15KB  |  495 lines

  1. /**************************************************************************
  2. ** File: nwsthrd.c
  3. **
  4. ** Desc: Example of using multi-threaded programs with NWSNUT
  5. **
  6. **    Disclaimer:
  7. **
  8. **        Novell, Inc. makes no representations or warranties with respect to
  9. **        any NetWare software, and specifically disclaims any express or
  10. **        implied warranties of merchantability, title, or fitness for a
  11. **        particular purpose.  
  12. **
  13. **        Distribution of any NetWare software is forbidden without the
  14. **        express written consent of Novell, Inc.  Further, Novell reserves
  15. **        the right to discontinue distribution of any NetWare software.
  16. **
  17. **        Novell is not responsible for lost profits or revenue, loss of use
  18. **        of the software, loss of data, costs of re-creating lost data, the
  19. **        cost of any substitute equipment or program, or claims by any party
  20. **        other than you.  Novell strongly recommends a backup be made before
  21. **        any software is installed.   Technical support for this software
  22. **        may be provided at the discretion of Novell.
  23. **
  24. **
  25. **    QMK386 options used:
  26. **
  27. **        /in                    Include import statement for NWSNUT symbols.
  28. **        /z                      Generate NLMLINKx version of def file.
  29. **        /ohNWSTHRD.HLP        Help file.
  30. **        /omNWSTHRD.MSG        Message file.
  31. **
  32. ** Programmers:
  33. **
  34. **    Ini   Who                  Firm
  35. **    ---------------------------------------------------------------------
  36. **    DWH   Dirk W. Howard       Novell Developer Support
  37. **
  38. **
  39. ** History:
  40. **
  41. **    When            Who   What
  42. **    ---------------------------------------------------------------------
  43. **    8-31-1994    DWH    First code.
  44. **
  45. */
  46.  
  47. /**************************************************************************
  48. ** Include files and macro definitions
  49. */
  50.    /*----------------------------------------------------------------------
  51.    ** ANSI Includes
  52.    */
  53.    #include <stdlib.h>    /* NULL */
  54.     #include <stdio.h>     /* sprintf(), printf() */
  55.     #include <string.h>  /* strlen()    */
  56.     #include <conio.h>     /*    GetCurrentScreen(), SetAutoScreenDestructionMode()    */
  57.    #include <signal.h>    /*    signal(), SIGTERM    */
  58.  
  59.    /*----------------------------------------------------------------------
  60.    ** NetWare Includes
  61.    */
  62.     #include <process.h>    /*    delay(), ThreadSwitchWithDelay(), GetNLMHandle(), BeginThread()    */
  63.     #include <errno.h>      /*    errno, ENO_SCRNS, EFAILURE, ENOMEM, EINVAL */
  64.     #include <nwsnut.h>    /*    Enough said?    */
  65.    #include <advanced.h>/* AllocateResourceTag(), AllocSignature    */
  66.  
  67.    /*----------------------------------------------------------------------
  68.    ** NWSTHRD
  69.    */
  70.    #include "nwsthrd.mlh"
  71.    #include "nwsthrd.hlh"
  72.    
  73.    #define FlagSet(arg1, arg2)   ((arg1) & (arg2))
  74.     #define PORTAL_TEXT_WIDTH        38
  75.  
  76. /**************************************************************************
  77. ** Global variables
  78. */
  79. int       NLM_shutdown        = FALSE;
  80. int       NLM_noUpdate        = FALSE;
  81. int       NLM_threadCount    = 0;
  82. NUTInfo  *NLM_nutHandle;
  83. PCB      *NLM_pPcb;
  84.  
  85. /**************************************************************************
  86. ** Generic Thread
  87. */
  88. void genericThread(void *arg)
  89.     {
  90.    LONG  count = 0;
  91.    LONG  threadNo = (LONG)arg;
  92.    char  message[128];
  93.    LONG  delayAmount = 1000 * threadNo;
  94.  
  95.    NLM_threadCount++;
  96.    while(TRUE)
  97.        {
  98.       if(NLM_shutdown)
  99.           {
  100.          sprintf(message, "Closing thread %d", threadNo);
  101.          NWSShowPortalLine(
  102.                 /* I-    line        */    threadNo,
  103.                 /*    I-    column    */    0,
  104.                 /*    I-    text        */    message,
  105.                 /* I-    length    */    PORTAL_TEXT_WIDTH,
  106.                 /*    I-    portal    */    NLM_pPcb
  107.                 );
  108.  
  109.          if(!NLM_nutHandle->helpActive && !NLM_nutHandle->errorDisplayActive)
  110.             NWSUpdatePortal(NLM_pPcb);
  111.          
  112.             NLM_threadCount--;
  113.             return;
  114.           }
  115.  
  116.       count++;
  117.       if((count % 10) && (NLM_noUpdate == FALSE))
  118.           {
  119.          sprintf( message, "Spinning in thread %d  %04d", threadNo, count );
  120.          NWSShowPortalLine(
  121.                 /* I-    line        */    threadNo,
  122.                 /*    I-    column    */    0,
  123.                 /*    I-    text        */    message,
  124.                 /* I-    length    */    PORTAL_TEXT_WIDTH,
  125.                 /*    I-    portal    */    NLM_pPcb
  126.                 );
  127.          if(!NLM_nutHandle->helpActive && !NLM_nutHandle->errorDisplayActive)
  128.             NWSUpdatePortal(NLM_pPcb);
  129.           }
  130.       delay(delayAmount);
  131.        }
  132.     }
  133.  
  134. /**************************************************************************
  135. ** AddToList Insert Procedure
  136. */
  137. int AddToList(BYTE *text, void **otherInfo, void *parameters)
  138.     {
  139.    int   ccode;
  140.  
  141.    otherInfo = otherInfo;
  142.    parameters = parameters;
  143.  
  144.    ccode = NWSEditString(
  145.         /*    I-    centerLine            */    16,
  146.         /* I-    centerColumn        */    40,
  147.         /*    I-    editHeight            */    1,
  148.         /*    I-    editWidth            */    PORTAL_TEXT_WIDTH,
  149.         /*    I-    header                */    INSERT_HEADER,
  150.         /*    I-    prompt                */    INSERT_PROMPT,
  151.         /*    I-    buf                    */    text,
  152.         /*    I-    maxLen                */    PORTAL_TEXT_WIDTH,
  153.         /*    I-    type                    */    EF_ANY,
  154.         /*    I-    handle                */    NLM_nutHandle,
  155.         /*    I-    insertProcedure    */    NULL,
  156.         /*    I-    actionProcedure    */    NULL,
  157.         /*    I-    parameters            */    NULL
  158.         );
  159.    if(FlagSet(ccode, E_ESCAPE|E_EMPTY)) return(1);
  160.  
  161.    return(0);
  162.     }
  163.  
  164.  
  165. /**************************************************************************
  166. ** ModifyElement Procedure
  167. */
  168. int ModifyElement(BYTE *text, void *parameters)
  169.     {
  170.    int   ccode;
  171.  
  172.    parameters = parameters;
  173.  
  174.    ccode = NWSEditString(
  175.         /*    I-    centerLine            */    16,
  176.         /* I-    centerColumn        */    40,
  177.         /*    I-    editHeight            */    1,
  178.         /*    I-    editWidth            */    PORTAL_TEXT_WIDTH,
  179.         /*    I-    header                */    INSERT_HEADER,
  180.         /*    I-    prompt                */    INSERT_PROMPT,
  181.         /*    I-    buf                    */    text,
  182.         /*    I-    maxLen                */    PORTAL_TEXT_WIDTH,
  183.         /*    I-    type                    */    EF_ANY,
  184.         /*    I-    handle                */    NLM_nutHandle,
  185.         /*    I-    insertProcedure    */    NULL,
  186.         /*    I-    actionProcedure    */    NULL,
  187.         /*    I-    parameters            */    NULL
  188.         );
  189.    if(FlagSet(ccode, E_ESCAPE|E_EMPTY)) return(1);
  190.    if(FlagSet( ccode, E_CHANGE )) return(0);
  191.    
  192.     return(1);
  193.     }
  194.  
  195. /**************************************************************************
  196. ** ListAction Procedure
  197. */
  198. int ListAction(LONG keyPressed, LIST **elementSelected, LONG *itemNumber, void *listParameter)
  199.     {
  200.    char  message[128];
  201.  
  202.    listParameter = listParameter;
  203.    itemNumber = itemNumber;
  204.  
  205.    switch (keyPressed)
  206.        {
  207.       case M_ESCAPE:
  208.          return(1);
  209.  
  210.       case M_SELECT:
  211.  
  212.          NWSShowPortalLine(
  213.                 /* I-    line        */    0,
  214.                 /*    I-    column    */    0,
  215.                 /*    I-    text        */    "",
  216.                 /* I-    length    */    PORTAL_TEXT_WIDTH,
  217.                 /*    I-    portal    */    NLM_pPcb
  218.                 );
  219.          if(!NLM_nutHandle->helpActive && !NLM_nutHandle->errorDisplayActive)
  220.             NWSUpdatePortal(NLM_pPcb);
  221.  
  222.          sprintf(message, "You selected : \"%s\"", (char *)((*elementSelected)->text));
  223.  
  224.          NWSShowPortalLine(
  225.                 /* I-    line        */    0,
  226.                 /*    I-    column    */    0,
  227.                 /*    I-    text        */    message,
  228.                 /* I-    length    */    strlen(message),
  229.                 /*    I-    portal    */    NLM_pPcb
  230.                 );
  231.          if(!NLM_nutHandle->helpActive && !NLM_nutHandle->errorDisplayActive)
  232.             NWSUpdatePortal(NLM_pPcb);
  233.  
  234.          return(-1);
  235.  
  236.       case M_INSERT:
  237.          NWSPushHelpContext(INSERT_HLP, NLM_nutHandle);
  238.          NWSInsertInPortalList(
  239.             /* I- currentElement      */  elementSelected,
  240.             /* I- currentLine       */  itemNumber,
  241.             /* I- insertProcedure    */  AddToList,
  242.             /* I- FreeProcedure       */  free,
  243.             /* I- handle                */  NLM_nutHandle,
  244.             /* I- parameters           */  NULL
  245.             );
  246.          NWSPopHelpContext(NLM_nutHandle);
  247.          return(-1);
  248.  
  249.       case M_DELETE:
  250.       case M_MDELETE:
  251.          NWSPushHelpContext(DELETE_HLP, NLM_nutHandle);
  252.          NLM_noUpdate = TRUE;
  253.          NWSDeleteFromPortalList(
  254.             /* I-    currentElement           */  elementSelected,
  255.             /* I-    currentLine                */  itemNumber,
  256.             /* I-    deleteProcedure          */  NULL,
  257.             /* I-    deleteCurrentMessageID     */  DELETE_CURRENT,
  258.             /* I-    deleteMarkedMessageID      */  DELETE_MARKED,
  259.             /* I-    handle                     */  NLM_nutHandle,
  260.             /* I-    parameters                */  NULL
  261.             );
  262.          NLM_noUpdate = FALSE;
  263.          NWSPopHelpContext(NLM_nutHandle);
  264.          return(-1);
  265.  
  266.       case M_MODIFY:
  267.          NWSPushHelpContext(MODIFY_HLP, NLM_nutHandle);
  268.          NWSModifyInPortalList(
  269.             /* I- currentElement        */ elementSelected,
  270.             /* I-    currentLine            */ itemNumber,
  271.             /* I-    ModifyProcedure    */ ModifyElement,
  272.             /* I-    handle             */ NLM_nutHandle,
  273.             /* I-    parameters        */ NULL
  274.             );
  275.          NWSPopHelpContext(NLM_nutHandle);
  276.          return(-1);
  277.  
  278.       default:
  279.          NWSShowPortalLine(
  280.                 /* I-    line        */    0,
  281.                 /*    I-    column    */    0,
  282.                 /*    I-    text        */    "",
  283.                 /* I-    length    */    PORTAL_TEXT_WIDTH,
  284.                 /*    I-    portal    */    NLM_pPcb
  285.                 );
  286.          if(!NLM_nutHandle->helpActive && !NLM_nutHandle->errorDisplayActive)
  287.             NWSUpdatePortal(NLM_pPcb);
  288.          
  289.             return(-1);         
  290.        }
  291.     }
  292.  
  293. /**************************************************************************
  294. ** WeWereUnloaded Procedure
  295. */
  296. void WeWereUnloaded(int sigtype)
  297.     {
  298.    sigtype = sigtype;
  299.    NLM_shutdown = TRUE;
  300.    
  301.     while(NLM_threadCount > 0)
  302.       ThreadSwitchWithDelay();
  303.  
  304.    NWSRestoreNut(NLM_nutHandle);
  305.     }
  306.  
  307. /**************************************************************************
  308. ** main procedure
  309. */
  310. void main(void)
  311.     {
  312.     LONG  nlmHandle;
  313.     LONG  nutAllocTag;
  314.    int   cCode;
  315.    LONG  lCode;
  316.     BYTE  bCode;
  317.    LONG  threadPortal;
  318.    LONG  portalTop = 4;           /* position at 1, 1 on physical screen */
  319.    LONG  portalLeft = 1;   
  320.    LONG  portalFrameHeight = 8;  /*  make the portal 8 X 40                 */
  321.    LONG  portalFrameWidth = 40;     
  322.    LONG  portalVirtualHeight = 4;/* make the virtual portal 4 X PORTAL_TEXT_WIDTH         */
  323.    LONG    portalVirtualWidth = PORTAL_TEXT_WIDTH;
  324.     LONG  threadCnt;
  325.     LIST *node;
  326.  
  327.    /*------------------------------------------------------------------------
  328.     ** Set-up
  329.     */
  330.    nlmHandle = GetNLMHandle();
  331.    bCode=SetAutoScreenDestructionMode(TRUE);
  332.     if(bCode == -1) switch(errno)
  333.         {
  334.         case ENO_SCRNS:
  335.             printf("ERROR:  SetAutoScreenDestructionMode() reports \"No Screens\".\n");
  336.             goto END;
  337.  
  338.         default:
  339.             printf("ERROR:  SetAutoScreenDestructionMode() reports unknown error: %d.\n", errno);
  340.             goto END;
  341.         }
  342.  
  343.    signal(SIGTERM, WeWereUnloaded);
  344.    
  345.     nutAllocTag = AllocateResourceTag(
  346.         /* I-    NLMHandle            */    nlmHandle,
  347.         /*    I-    descriptionString    */    "NWSThrd_NUT",
  348.         /*    I-    resoruceType        */    AllocSignature
  349.         );
  350.    if(!nutAllocTag)
  351.         {
  352.         printf("ERROR:  AllocResoruceTag() failed.\n");
  353.         goto END;
  354.         }
  355.  
  356.    lCode = NWSInitializeNut(
  357.        /*    I-    Utility                */    NAME,
  358.       /*    I- version                */    VERSION,
  359.         /*    I-    headerType            */    NORMAL_HEADER,
  360.       /*    I- compatibilityType    */ 0,
  361.       /*    I- messageTable        */    NULL,
  362.         /*    I-    helpScreens            */    NULL,
  363.         /*    I-    screenID                */    GetCurrentScreen(),
  364.         /*    I-    resourceTag            */    nutAllocTag,
  365.         /*    -O handle                */    &NLM_nutHandle
  366.       );
  367.     switch(lCode)
  368.         {
  369.         case 0:
  370.             break;
  371.  
  372.         default:
  373.             printf("ERROR:  NWSInitializeNut() failed. [%d]\n", lCode);
  374.             goto END;
  375.         }
  376.  
  377.    NWSDisplayPreHelp(
  378.         /*    I-    line        */    22,
  379.         /*    I-    column    */    40,
  380.         /*    I-    message    */    PREHELP_MSG,
  381.         /*    I    handle    */    NLM_nutHandle
  382.         );
  383.    NWSPushHelpContext(MAIN_HLP, NLM_nutHandle);
  384.  
  385.    threadPortal = NWSCreatePortal(
  386.        /*    I-    line                    */    portalTop, 
  387.       /*    I-    column                */    portalLeft,
  388.       /*    I-    frameHeight            */    portalFrameHeight, 
  389.       /*    I-    frameWidth            */    portalFrameWidth, 
  390.       /*    I-    virtualHeight        */    portalVirtualHeight,
  391.       /*    I-    virtualWidth        */    portalVirtualWidth, 
  392.       /*    I-    saveFlag                */    SAVE, 
  393.       /*    I-    headerText            */    "Thread Portal", 
  394.       /*    I-    headerAttribute    */    0,
  395.       /*    I-    borderType            */    DOUBLE, 
  396.       /*    I-    borderAttribute    */    0, 
  397.       /*    I-    cursorFlag            */    CURSOR_ON, 
  398.       /*    I-    directFlag            */    VIRTUAL, 
  399.       /*    I-    handle                */    NLM_nutHandle
  400.       );
  401.    switch(threadPortal)
  402.         {
  403.         case 0xFFFFFFFEL:
  404.             NWSTrace(NLM_nutHandle, "ERROR:  NWSCreatePortal() indicated: \"Out of memory\"");
  405.             goto END;
  406.  
  407.         case 0xFFFFFFFFL:
  408.             NWSTrace(NLM_nutHandle, "ERROR:  NWSCreatePortal() indicated: \"Max number of portals already defined.\"");
  409.             goto END;
  410.  
  411.         /*---------------------------------------------------------------------
  412.         **    If not one of the above documented values, value is an address.
  413.         */
  414.         default:    
  415.             break;
  416.        }
  417.  
  418.    NWSGetPCB(
  419.         /* -O    pPcb                */    &NLM_pPcb,
  420.         /*    I-    portalNumber    */    threadPortal,
  421.         /*    I-    handle            */    NLM_nutHandle
  422.         );
  423.  
  424.    /*------------------------------------------------------------------------
  425.     **    Build, display and interact with list.
  426.     */
  427.     for(threadCnt = 1L; threadCnt <= 3; ++threadCnt)
  428.         {
  429.        cCode=BeginThread(
  430.             /*    I-    funct            */    genericThread,
  431.             /*    I-    stack            */    NULL,
  432.             /*    I-    stackSize    */    0,
  433.             /*    I-    arg            */ (void *)threadCnt
  434.             );
  435.        if(cCode == EFAILURE) switch(errno)
  436.            {
  437.           case ENOMEM:
  438.                 NWSTrace(NLM_nutHandle, "ERROR:  BeginThread() indicated \"Not enough memory\"\n");
  439.                 goto END;
  440.  
  441.             case EINVAL:
  442.                 NWSTrace(NLM_nutHandle, "ERROR:  BeginThread() indicated \"Invalid arg was passed in.\"\n");
  443.                 goto END;
  444.  
  445.             default:
  446.                 NWSTrace(NLM_nutHandle, "ERROR:  BeginThread() returned unknown error: %d.\n", cCode);
  447.                 goto END;
  448.            }
  449.         }
  450.  
  451.    NWSInitList(
  452.         /*    I-    handle        */    NLM_nutHandle,
  453.         /*    i-    freeRoutine    */    free
  454.         );
  455.  
  456.    node=NWSAppendToList("Test Item", NULL, NLM_nutHandle);
  457.     if(node == NULL) NWSTrace(NLM_nutHandle, "ERROR:  NWSAppendToList(#1) failed.\n");
  458.  
  459.    NWSAppendToList("Another Test Item", NULL, NLM_nutHandle);
  460.     if(node == NULL) NWSTrace(NLM_nutHandle, "ERROR:  NWSAppendToList(#2) failed.\n");
  461.    
  462.    NWSList(
  463.         /*    header                */    LIST_HEADER,
  464.         /*    centerLine            */    4,
  465.         /*    centerColumn        */    55,
  466.         /*    height                */    4, 
  467.       /*    width                    */    strlen(NWSGetMessage(LIST_HEADER, &(NLM_nutHandle->messages))) +4, 
  468.       /*    validKeyFlags        */    M_ESCAPE|M_SELECT|M_INSERT|M_DELETE|M_MDELETE|M_MODIFY, 
  469.         /*    element                */    NULL,
  470.         /*    handle                */    NLM_nutHandle,
  471.         /*    formatProcedure    */    NULL,
  472.         /*    actionProcedure    */    ListAction,
  473.         /*    actionParameter    */    NULL
  474.         );
  475.  
  476.    /*------------------------------------------------------------------------
  477.     **    close down
  478.     */
  479.    NLM_shutdown = TRUE;
  480.     while(NLM_threadCount > 0) ThreadSwitchWithDelay();
  481.     delay(1000);
  482.     NWSDestroyPortal(
  483.         /*    portalNumber    */    threadPortal,
  484.         /*    handle            */    NLM_nutHandle
  485.       );
  486.    NWSRestoreNut(NLM_nutHandle);
  487.  
  488. END:
  489.  
  490.     return;
  491.     }
  492.  
  493.  
  494.  
  495.