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 >
Wrap
C/C++ Source or Header
|
1988-04-28
|
4KB
|
191 lines
/* Primitive test program for LoadIPCPort facility */
/* ...simply displays a request for a port in its console window */
#include "IPCPorts.h"
#include "IPC.h"
#include "exec/memory.h"
#include "exec/tasks.h"
#include "libraries/DOS.h"
#define SOL(s) ((LONG)sizeof(s))
#define IPPL MAKE_ID('I','P','P','L')
#define PORT MAKE_ID('P','O','R','T')
struct IPCPort *brokerport; /* actually IPCBasePort -- for convenience */
struct IPCMessage *imsg=NULL;
void baditem(struct IPCItem *, ULONG);
void outputstr(char *);
struct Task * FindTask(char *);
struct IPCPort * ServeIPCBase();
void ShutIPCBase();
void LeaveIPCBase();
void Cleanup();
ULONG bportsig = 0; /* signal masks for port */
int active = TRUE;
void _main()
{
ULONG sigset;
brokerport = ServeIPCBase();
if (!brokerport) _exit(11);
bportsig = 1<<brokerport->ipp_Port.mp_SigBit;
do {
while ( procimsg() ) ; /* loop */
if (active) {
sigset = Wait(bportsig | SIGBREAKF_CTRL_C);
if (sigset & SIGBREAKF_CTRL_C) {
active = FALSE;
ShutIPCBase(); /* not really necessary... */
continue; /* so we clear out any messages that sneak in */
}
}
} while (active);
outputstr("Broker terminating...\n");
Cleanup();
}
void Cleanup()
{
LeaveIPCBase();
}
procimsg()
{
struct IPCItem *item;
if (!(imsg = (struct IPCMessage *) GetMsg(brokerport))) return FALSE;
item = imsg->ipc_Items;
if (imsg->ipc_Id == IPPL && item->ii_Id == PORT
&& loadport(item->ii_Ptr)) /* everything OK */;
else imsg->ipc_Flags |= IPC_NOTKNOWN;
ReplyMsg(imsg);
return TRUE;
}
void baditem(item, extraflags)
struct IPCItem *item;
ULONG extraflags;
{
imsg->ipc_Flags |= IPC_CHECKITEM;
item->ii_Flags |= IPC_NOTKNOWN | extraflags;
}
void outputstr(str) char *str;
{
Write(Output(), str, strlen(str));
}
/*
* loadport(portptr)
*
* -- actually initiates the loading procedure (here just a skeleton).
* returns TRUE if successful, otherwise FALSE.
*/
loadport(port) struct IPCPort *port;
{
outputstr("Please load server for port '");
outputstr(port->ipp_Name);
outputstr("' -- Thanks\n");
port->ipp_Flags |= IPP_LOADING;
return TRUE; /* -- doesn't know how to fail yet... */
}
/****************************************************************/
/*
* The following procedures are simple conversions (the first is
* a direct copy) of the corresponding ones in IPC.c.
* The standard IPC module itself is not needed.
*/
struct IPCBasePort *IPCBasePort = NULL;
struct IPCBasePort * OpenIPCBase()
{
char * pname = "IPC_Base_Port";
struct MsgPort * port;
if (IPCBasePort) return IPCBasePort;
Forbid();
if (!(IPCBasePort = (struct IPCBasePort *)FindPort(pname))) {
IPCBasePort = (struct IPCBasePort *)
AllocMem(SOL(struct IPCBasePort), MEMF_CLEAR | MEMF_PUBLIC);
if (IPCBasePort) {
port = & IPCBasePort->ipcb_Port.ipp_Port;
port->mp_Node.ln_Name = IPCBasePort->ipcb_Port.ipp_Name;
port->mp_Node.ln_Type = NT_MSGPORT;
AddPort(port);
NewList(&(IPCBasePort->ipcb_PortList));
strcpy(IPCBasePort->ipcb_Port.ipp_Name, pname);
}
}
Permit();
return IPCBasePort;
}
struct IPCPort * ServeIPCBase()
{
struct IPCPort * port;
port = (struct IPCPort *)OpenIPCBase();
if (port) {
Forbid();
if ((port->ipp_Flags & (IPP_SERVED))
|| (port->ipp_Port.mp_SigBit = AllocSignal(-1L)) == -1L) {
port = NULL;
}
else {
port->ipp_Port.mp_Flags = PA_SIGNAL;
port->ipp_Port.mp_SigTask = FindTask(NULL);
port->ipp_Flags = IPP_SERVED; /* all other bits cleared */
}
Permit();
}
return port;
}
void ShutIPCBase()
{
struct IPCPort *port;
if (!IPCBasePort) return;
port = &IPCBasePort->ipcb_Port;
port->ipp_Flags |= IPP_SHUT; /* Prevent other servers connecting */
port->ipp_Flags &= ~IPP_SERVED; /* prevent messages from landing */
port->ipp_Port.mp_Flags = PA_IGNORE; /* someone might use PutMsg! */
}
void LeaveIPCBase()
{
struct IPCPort *port;
if (!IPCBasePort) return;
port = &IPCBasePort->ipcb_Port;
FreeSignal(port->ipp_Port.mp_SigBit);
port->ipp_Port.mp_SigTask = NULL;
port->ipp_Flags = 0;
}