00001 // post.h 00002 // Data structures for providing the abstraction of unreliable, 00003 // ordered, fixed-size message delivery to mailboxes on other 00004 // (directly connected) machines. Messages can be dropped by 00005 // the network, but they are never corrupted. 00006 // 00007 // The US Post Office delivers mail to the addressed mailbox. 00008 // By analogy, our post office delivers packets to a specific buffer 00009 // (MailBox), based on the mailbox number stored in the packet header. 00010 // Mail waits in the box until a thread asks for it; if the mailbox 00011 // is empty, threads can wait for mail to arrive in it. 00012 // 00013 // Thus, the service our post office provides is to de-multiplex 00014 // incoming packets, delivering them to the appropriate thread. 00015 // 00016 // With each message, you get a return address, which consists of a "from 00017 // address", which is the id of the machine that sent the message, and 00018 // a "from box", which is the number of a mailbox on the sending machine 00019 // to which you can send an acknowledgement, if your protocol requires 00020 // this. 00021 // 00022 // Copyright (c) 1992-1993 The Regents of the University of California. 00023 // All rights reserved. See copyright.h for copyright notice and limitation 00024 // of liability and disclaimer of warranty provisions. 00025 00026 #include "copyright.h" 00027 00028 #ifndef POST_H 00029 #define POST_H 00030 00031 #include "network.h" 00032 #include "synchlist.h" 00033 00034 // Mailbox address -- uniquely identifies a mailbox on a given machine. 00035 // A mailbox is just a place for temporary storage for messages. 00036 typedef int MailBoxAddress; 00037 00038 // The following class defines part of the message header. 00039 // This is prepended to the message by the PostOffice, before the message 00040 // is sent to the Network. 00041 00042 class MailHeader { 00043 public: 00044 MailBoxAddress to; // Destination mail box 00045 MailBoxAddress from; // Mail box to reply to 00046 unsigned length; // Bytes of message data (excluding the 00047 // mail header) 00048 }; 00049 00050 // Maximum "payload" -- real data -- that can included in a single message 00051 // Excluding the MailHeader and the PacketHeader 00052 00053 #define MaxMailSize (MaxPacketSize - sizeof(MailHeader)) 00054 00055 00056 // The following class defines the format of an incoming/outgoing 00057 // "Mail" message. The message format is layered: 00058 // network header (PacketHeader) 00059 // post office header (MailHeader) 00060 // data 00061 00062 class Mail { 00063 public: 00064 Mail(PacketHeader pktH, MailHeader mailH, char *msgData); 00065 // Initialize a mail message by 00066 // concatenating the headers to the data 00067 00068 PacketHeader pktHdr; // Header appended by Network 00069 MailHeader mailHdr; // Header appended by PostOffice 00070 char data[MaxMailSize]; // Payload -- message data 00071 }; 00072 00073 // The following class defines a single mailbox, or temporary storage 00074 // for messages. Incoming messages are put by the PostOffice into the 00075 // appropriate mailbox, and these messages can then be retrieved by 00076 // threads on this machine. 00077 00078 class MailBox { 00079 public: 00080 MailBox(); // Allocate and initialize mail box 00081 ~MailBox(); // De-allocate mail box 00082 00083 void Put(PacketHeader pktHdr, MailHeader mailHdr, char *data); 00084 // Atomically put a message into the mailbox 00085 void Get(PacketHeader *pktHdr, MailHeader *mailHdr, char *data); 00086 // Atomically get a message out of the 00087 // mailbox (and wait if there is no message 00088 // to get!) 00089 private: 00090 SynchList *messages; // A mailbox is just a list of arrived messages 00091 }; 00092 00093 // The following class defines a "Post Office", or a collection of 00094 // mailboxes. The Post Office is a synchronization object that provides 00095 // two main operations: Send -- send a message to a mailbox on a remote 00096 // machine, and Receive -- wait until a message is in the mailbox, 00097 // then remove and return it. 00098 // 00099 // Incoming messages are put by the PostOffice into the 00100 // appropriate mailbox, waking up any threads waiting on Receive. 00101 00102 class PostOffice { 00103 public: 00104 PostOffice(NetworkAddress addr, double reliability, int nBoxes); 00105 // Allocate and initialize Post Office 00106 // "reliability" is how many packets 00107 // get dropped by the underlying network 00108 ~PostOffice(); // De-allocate Post Office data 00109 00110 void Send(PacketHeader pktHdr, MailHeader mailHdr, char *data); 00111 // Send a message to a mailbox on a remote 00112 // machine. The fromBox in the MailHeader is 00113 // the return box for ack's. 00114 00115 void Receive(int box, PacketHeader *pktHdr, 00116 MailHeader *mailHdr, char *data); 00117 // Retrieve a message from "box". Wait if 00118 // there is no message in the box. 00119 00120 void PostalDelivery(); // Wait for incoming messages, 00121 // and then put them in the correct mailbox 00122 00123 void PacketSent(); // Interrupt handler, called when outgoing 00124 // packet has been put on network; next 00125 // packet can now be sent 00126 void IncomingPacket(); // Interrupt handler, called when incoming 00127 // packet has arrived and can be pulled 00128 // off of network (i.e., time to call 00129 // PostalDelivery) 00130 00131 private: 00132 Network *network; // Physical network connection 00133 NetworkAddress netAddr; // Network address of this machine 00134 MailBox *boxes; // Table of mail boxes to hold incoming mail 00135 int numBoxes; // Number of mail boxes 00136 Semaphore *messageAvailable;// V'ed when message has arrived from network 00137 Semaphore *messageSent; // V'ed when next message can be sent to network 00138 Lock *sendLock; // Only one outgoing message at a time 00139 }; 00140 00141 #endif
1.2.14 written by Dimitri van Heesch,
© 1997-2002