home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 164.lha / IPC / Sources / Broker.c < prev    next >
C/C++ Source or Header  |  1988-04-28  |  4KB  |  191 lines

  1. /* Primitive test program for LoadIPCPort facility */
  2. /* ...simply displays a request for a port in its console window */
  3.  
  4. #include "IPCPorts.h"
  5. #include "IPC.h"
  6.  
  7. #include "exec/memory.h"
  8. #include "exec/tasks.h"
  9. #include "libraries/DOS.h"
  10.  
  11. #define  SOL(s)  ((LONG)sizeof(s))
  12.  
  13. #define IPPL MAKE_ID('I','P','P','L')
  14. #define PORT MAKE_ID('P','O','R','T')
  15.  
  16.  
  17. struct IPCPort *brokerport; /* actually IPCBasePort -- for convenience */
  18. struct IPCMessage *imsg=NULL;
  19.  
  20. void baditem(struct IPCItem *, ULONG);
  21. void outputstr(char *);
  22.  
  23. struct Task * FindTask(char *);
  24.  
  25. struct IPCPort * ServeIPCBase();
  26. void ShutIPCBase();
  27. void LeaveIPCBase();
  28. void Cleanup();
  29.  
  30.  
  31. ULONG bportsig = 0;  /* signal masks for port */
  32.  
  33. int active = TRUE;
  34.  
  35.  
  36. void _main()
  37. {
  38.     ULONG sigset;
  39.  
  40.     brokerport = ServeIPCBase();
  41.     if (!brokerport) _exit(11);
  42.     bportsig = 1<<brokerport->ipp_Port.mp_SigBit;
  43.  
  44.  
  45.     do {
  46.         while ( procimsg() ) ;    /* loop */
  47.         if (active) {
  48.             sigset = Wait(bportsig | SIGBREAKF_CTRL_C);
  49.             if (sigset & SIGBREAKF_CTRL_C) {
  50.                 active = FALSE;
  51.                 ShutIPCBase(); /* not really necessary... */
  52.                 continue; /* so we clear out any messages that sneak in */
  53.             }
  54.         }
  55.     } while (active);
  56.     outputstr("Broker terminating...\n");
  57.  
  58.     Cleanup();
  59. }
  60.  
  61.  
  62. void Cleanup()
  63. {
  64.     LeaveIPCBase();
  65. }
  66.  
  67.  
  68. procimsg()
  69. {
  70.     struct IPCItem *item;
  71.     if (!(imsg = (struct IPCMessage *) GetMsg(brokerport))) return FALSE;
  72.     item = imsg->ipc_Items;
  73.     if (imsg->ipc_Id == IPPL && item->ii_Id == PORT
  74.         && loadport(item->ii_Ptr)) /* everything OK */;
  75.     else imsg->ipc_Flags |= IPC_NOTKNOWN;
  76.     ReplyMsg(imsg);
  77.     return TRUE;
  78. }
  79.  
  80.  
  81. void baditem(item, extraflags)
  82.     struct IPCItem *item;
  83.     ULONG extraflags;
  84. {
  85.     imsg->ipc_Flags |= IPC_CHECKITEM;
  86.     item->ii_Flags |= IPC_NOTKNOWN | extraflags;
  87. }
  88.  
  89. void outputstr(str) char *str;
  90. {
  91.     Write(Output(), str, strlen(str));
  92. }
  93.  
  94.  
  95. /*
  96.  *  loadport(portptr)
  97.  *
  98.  *  -- actually initiates the loading procedure (here just a skeleton).
  99.  *      returns TRUE if successful, otherwise FALSE.
  100.  */
  101.  
  102. loadport(port) struct IPCPort *port;
  103. {
  104.     outputstr("Please load server for port '");
  105.     outputstr(port->ipp_Name);
  106.     outputstr("' -- Thanks\n");
  107.     port->ipp_Flags |= IPP_LOADING;
  108.     return TRUE; /* -- doesn't know how to fail yet... */
  109. }
  110.  
  111.  
  112. /****************************************************************/
  113.  
  114. /*
  115.  *  The following procedures are simple conversions (the first is
  116.  *  a direct copy) of the corresponding ones in IPC.c.
  117.  *  The standard IPC module itself is not needed.
  118.  */
  119.  
  120. struct IPCBasePort *IPCBasePort = NULL;
  121.  
  122.  
  123. struct IPCBasePort * OpenIPCBase()
  124. {
  125.     char * pname = "IPC_Base_Port";
  126.     struct MsgPort * port;
  127.  
  128.     if (IPCBasePort) return IPCBasePort;
  129.     Forbid();
  130.     if (!(IPCBasePort = (struct IPCBasePort *)FindPort(pname))) {
  131.         IPCBasePort = (struct IPCBasePort *)
  132.             AllocMem(SOL(struct IPCBasePort), MEMF_CLEAR | MEMF_PUBLIC);
  133.         if (IPCBasePort) {
  134.             port = & IPCBasePort->ipcb_Port.ipp_Port;
  135.             port->mp_Node.ln_Name = IPCBasePort->ipcb_Port.ipp_Name;
  136.             port->mp_Node.ln_Type = NT_MSGPORT;
  137.             AddPort(port);
  138.             NewList(&(IPCBasePort->ipcb_PortList));
  139.             strcpy(IPCBasePort->ipcb_Port.ipp_Name, pname);
  140.         }
  141.     }
  142.     Permit();
  143.     return IPCBasePort;
  144. }
  145.  
  146.  
  147.  
  148. struct IPCPort * ServeIPCBase()
  149. {
  150.     struct IPCPort * port;
  151.  
  152.     port = (struct IPCPort *)OpenIPCBase();
  153.     if (port) {
  154.         Forbid();
  155.         if ((port->ipp_Flags & (IPP_SERVED))
  156.          || (port->ipp_Port.mp_SigBit = AllocSignal(-1L)) == -1L) {
  157.             port = NULL;
  158.         }
  159.         else {
  160.             port->ipp_Port.mp_Flags = PA_SIGNAL;
  161.             port->ipp_Port.mp_SigTask = FindTask(NULL);
  162.             port->ipp_Flags = IPP_SERVED; /* all other bits cleared */
  163.         }
  164.         Permit();
  165.     }
  166.     return port;
  167. }
  168.  
  169. void ShutIPCBase()
  170. {
  171.     struct IPCPort *port;
  172.     if (!IPCBasePort) return;
  173.     port = &IPCBasePort->ipcb_Port;
  174.     port->ipp_Flags |= IPP_SHUT; /* Prevent other servers connecting */
  175.     port->ipp_Flags &= ~IPP_SERVED; /* prevent messages from landing */
  176.     port->ipp_Port.mp_Flags = PA_IGNORE; /* someone might use PutMsg! */
  177. }
  178.  
  179.  
  180. void LeaveIPCBase()
  181. {
  182.     struct IPCPort *port;
  183.     if (!IPCBasePort) return;
  184.     port = &IPCBasePort->ipcb_Port;
  185.     FreeSignal(port->ipp_Port.mp_SigBit);
  186.     port->ipp_Port.mp_SigTask = NULL;
  187.     port->ipp_Flags = 0;
  188. }
  189.  
  190.  
  191.