home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 7 / FreshFishVol7.bin / bbs / gnu / aplusplus-1.01-src.lha / GNU / src / amiga / APlusPlus-1.01 / libsource / TimedMsgPort.cxx < prev    next >
C/C++ Source or Header  |  1994-04-23  |  5KB  |  201 lines

  1. /******************************************************************************
  2.  **
  3.  **    C++ Class Library for the Amiga© system software.
  4.  **
  5.  **    Copyright (C) 1994 by Armin Vogt  **  EMail: armin@uni-paderborn.de
  6.  **    All Rights Reserved.
  7.  **
  8.  **    $Source: apphome:APlusPlus/RCS/libsource/TimedMsgPort.cxx,v $
  9.  **    $Revision: 1.3 $
  10.  **    $Date: 1994/04/23 21:02:48 $
  11.  **    $Author: Armin_Vogt $
  12.  **
  13.  ******************************************************************************/
  14.  
  15.  
  16. #include <APlusPlus/exec/TimedMsgPort.h>
  17. #include <string.h>
  18.  
  19.  
  20. #define TIMEOUT_SECS 5
  21. // timeout is 5 seconds after sending
  22.  
  23.  
  24. volatile static char rcs_id[] = "$Id: TimedMsgPort.cxx,v 1.3 1994/04/23 21:02:48 Armin_Vogt Exp Armin_Vogt $";
  25.  
  26.  
  27. TimedMsgPort::TimedMsgPort(struct MsgPort *port,UWORD sendWindowSize) 
  28.     : SignalResponder((BYTE)port->mp_SigBit,0),sendWindow(sendWindowSize)
  29.     hasCreatedPort = FALSE; 
  30.     setID(MSGRESPONDER_CLASS); 
  31. }
  32.  
  33. TimedMsgPort::TimedMsgPort(const UBYTE *portName,BYTE portPri,UWORD sendWindowSize)
  34.    : SignalResponder(0,0), sendWindow(sendWindowSize)
  35. {
  36.    if (port = CreateMsgPort())
  37.    {
  38.       changeSignalBit(port->mp_SigBit);
  39.       port->mp_Node.ln_Name = (char*)portName;
  40.       port->mp_Node.ln_Pri  = portPri;
  41.       if (portName)  AddPort(port);
  42.       hasCreatedPort = TRUE;
  43.       setID(MSGRESPONDER_CLASS);
  44.    }
  45.    else _ierror(MSGPORTRESPONDER_CREATEMSGPORT_FAILED);
  46. }
  47.  
  48. TimedMsgPort::~TimedMsgPort()
  49. {
  50.    if (hasCreatedPort == TRUE)
  51.    {
  52.       // if port is public remove from public port list
  53.       if (FindPort((UBYTE*)port->mp_Node.ln_Name)) RemPort(port);
  54.  
  55.       // reply all messages still in the message queue
  56.       MessageC *msg;
  57.       Forbid();
  58.       while (NULL != (msg = (MessageC*)GetMsg(port))) msg->replyMsg();
  59.       DeleteMsgPort(port);
  60.       Permit();
  61.    }
  62. }
  63.  
  64. void TimedMsgPort::actionCallback()
  65.    /* get the message from the port an call the virtual message processing method.
  66.       The message will not be replied from this instance. This must be done in processMsg()
  67.       or somewhere later.
  68.    */
  69. {
  70.    MessageC *msg;
  71.  
  72.    while (NULL != (msg = (MessageC*)GetMsg(port)))
  73.    {
  74.         msg->signRemoved();    // change MessageC MsgState from MSG_SENT to MSG_IN_PROCESS
  75.  
  76.         if (msg->getMsgState() == MSG_REPLIED)
  77.         {
  78.             // remove the replied message from the sending window
  79.             if (sendWindow.remove(msg))
  80.             {
  81.                 processReply(msg);
  82.             }
  83.             else // Timer message replied
  84.             {
  85.                 if (sendWindow.timeout(msg))
  86.                 {
  87.                     cerr << "TimedMsgPort : message timed out!\n";
  88.                 }
  89.                 else // was no timer message !?
  90.                 {
  91.                     cerr << "TimedMsgPort : Foreign message received.\n";
  92.                 }
  93.             }
  94.         }
  95.         else // no reply message
  96.         {
  97.             processMsg(msg);
  98.             msg->replyMsg();
  99.         }
  100.    }
  101. }
  102.  
  103. BOOL TimedMsgPort::sendMsgToPort(MessageC *msg,struct MsgPort *mp)
  104. {
  105.     TimerC *timeout;
  106.     msg->setReplyPort(port);    // set reply port before inserting the message!
  107.  
  108.     if (NULL != (timeout = sendWindow.insert(msg)) )
  109.     {
  110.         if (mp->mp_Node.ln_Type == NT_MSGPORT && mp->mp_MsgList.lh_Head != (struct Node*)-1)
  111.         {
  112.             timeout->start();
  113.             PutMsg(mp,msg);
  114.             return TRUE;
  115.         }
  116.         else cerr << "TimedMsgPort::sendMsgToPort : destination port is not valid!\n";
  117.     }
  118.     return FALSE;
  119. }
  120.  
  121. BOOL TimedMsgPort::sendMsgToPort(MessageC *message,const UBYTE *destinationName)
  122. {
  123.     struct MsgPort *mp;
  124.     BOOL rv = FALSE;
  125.     Forbid();
  126.     if (NULL != (mp = FindPort((UBYTE*)destinationName)) ) 
  127.         rv = sendMsgToPort(message,mp);
  128.     Permit();
  129.     return rv;
  130. }
  131.  
  132. //--------------------- SendingWindow -------------------------------
  133. struct MsgEntry 
  134. {
  135.     MessageC *message;    // sent message
  136.     TimerC    *timeout;    // timer set up for time out on the message    
  137. };
  138.  
  139. TimedMsgPort::SendingWindow::SendingWindow(UWORD size)
  140. {
  141.     entryTable = new MsgEntry[entries=size];
  142.     memset(entryTable,0,sizeof(MsgEntry)*size);    
  143. }
  144.  
  145. TimedMsgPort::SendingWindow::~SendingWindow()
  146.     MsgEntry *entry = entryTable;
  147.     for (UWORD n=entries; n>0; n--,entry++)
  148.         if (entry->timeout) delete entry->timeout;
  149.         
  150.     delete [] entryTable;
  151. }
  152.  
  153. TimerC *TimedMsgPort::SendingWindow::insert(MessageC *msg)
  154. {
  155.     MsgEntry *entry = entryTable;
  156.     for (UWORD n=entries; n>0; n--,entry++)
  157.         if (entry->message==NULL)
  158.         {
  159.             if (entry->timeout==NULL)
  160.                 if ( !(entry->timeout = new TimerC(UNIT_VBLANK,msg->getReplyPort())) )
  161.                     return NULL;
  162.                 else entry->timeout->set(TIMEOUT_SECS);
  163.                     
  164.             entry->message = msg;
  165.             return entry->timeout;
  166.         } 
  167.         
  168.     return NULL;
  169. }
  170.  
  171. BOOL TimedMsgPort::SendingWindow::remove(MessageC *msg)
  172. {
  173.     MsgEntry *entry = entryTable;
  174.     for (UWORD n=entries; n>0; n--,entry++)
  175.         if (entry->message == msg)
  176.         {
  177.             entry->timeout->abort();
  178.             entry->message == NULL;
  179.             return TRUE;
  180.         }
  181.         
  182.     return FALSE;
  183. }
  184.  
  185. MessageC *TimedMsgPort::SendingWindow::timeout(MessageC *timerMsg)
  186. {
  187.     MsgEntry *entry = entryTable;
  188.     for (UWORD n=entries; n>0; n--,entry++)
  189.         if (entry->timeout->getMessage() == timerMsg)
  190.         {
  191.             entry->timeout->reuse();
  192.             MessageC *timedOutMsg = entry->message;
  193.             entry->message = NULL;
  194.             return timedOutMsg;
  195.         }
  196.         
  197.     return NULL;
  198. }
  199.