From ba066c34dde204aa192d03a23a81356374d93731 Mon Sep 17 00:00:00 2001 From: chatty Date: Wed, 7 Apr 1993 11:50:31 +0000 Subject: Initial revision --- comm/OLD/Service.cc | 328 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 328 insertions(+) create mode 100644 comm/OLD/Service.cc (limited to 'comm/OLD/Service.cc') diff --git a/comm/OLD/Service.cc b/comm/OLD/Service.cc new file mode 100644 index 0000000..618214b --- /dev/null +++ b/comm/OLD/Service.cc @@ -0,0 +1,328 @@ +/* + * The Unix Channel + * + * by Michel Beaudouin-Lafon + * + * Copyright 1990-1993 + * Laboratoire de Recherche en Informatique (LRI) + * + * Client side: services + * + * $Id$ + * $CurLog$ + */ + +#include "Service.h" + +/*?class UchService +An object of class \typ{UchService} (derived from \typ{UchMsgStream}) exists in a client process +to represent the server it is connected to. + +The class \typ{UchService} is virtual: you must create subclasses that redefine +at least \fun{NewMessage} from class \fun{UchMsgStream}, and if necessary \fun{ConvertAnswer}. +\fun{NewMessage} should decipher the incoming message, transform it into an event, +and put in into the event queue with \fun{PutEvent}. +It can also handle non event messages (for instance errors). +?*/ + +/*?class UchEvtMsgQueue +An event queue is a linked list of events. +Events are normally appended to the end of the queue and extracted from the beginning. +?*/ + +/*?nodoc?*/ +UchEvtMsgQueue :: UchEvtMsgQueue () +: CcuSmartData (), + Queue () +{ +} + +/*?nodoc?*/ +UchEvtMsgQueue :: ~UchEvtMsgQueue () +{ +} + +#ifdef DOC +/*? +Append an event to the queue. +?*/ +void +UchEvtMsgQueue :: Put (UchEventMsg* msg) +{ +} + +/*? +Put an event back in the queue (therefore it becomes the first event of the queue). +?*/ +void +UchEvtMsgQueue :: PutBack (UchEventMsg* msg) +{ +} + +/*? +Return the first event from the queue and remove it. +?*/ +UchEventMsg* +UchEvtMsgQueue :: Get () +{ +} + +/*? +Return the first event from the queue without removing it. +?*/ +UchEventMsg* +UchEvtMsgQueue :: Peek () +{ +} + +#endif /* DOC */ + + +/*? +Construct an empty service. +?*/ +UchService :: UchService () +: UchMsgStream (), + EvQueue (0) +{ +} + +/*? +Construct a service connected to address \var{a}. +?*/ +UchService :: UchService (UchAddress* a) +: UchMsgStream (0, a), + EvQueue (0) +{ +} + +/*?nodoc?*/ +UchService :: UchService (const UchService& s) +: UchMsgStream (s), + EvQueue (s.EvQueue) +{ +} + +/*?nodoc?*/ +UchService :: ~UchService () +{ + EvQueue = 0; // deletes it +} + +/*?nodoc?*/ +UchChannel* +UchService :: Copy () const +{ + return new UchService (*this); +} + +/*? +Set the event queue to be used to store the incoming events. +If not set, a default event queue is created. +This function is intended to share a queue between several servers. +?*/ +void +UchService :: SetEvQueue (UchEvtMsgQueue* evq) +{ + EvQueue = evq; +} + +/*?nextdoc?*/ +UchEventMsg* +UchService :: PeekEvent (bool wait) +{ + Flush (); + if (!EvQueue) + EvQueue = new UchEvtMsgQueue; + UchEventMsg* ev = EvQueue->Peek (); + if (ev || ! wait) + return ev; + while (! ev) { + HandleRead (); + ev = EvQueue->Peek (); + } + return ev; +} + +/*? +These functions flush the output buffer, and check the events already in the queue. +If there is at least one, it is returned; +\fun{GetEvent} also removes it from the event queue. +If the event queue is empty and \var{wait} is TRUE, the function blocks until an event arrives, +else it returns 0 without blocking. +These functions also create the event queue if it was not set with \fun{SetEvQueue}. +?*/ +UchEventMsg* +UchService :: GetEvent (bool wait) +{ + Flush (); + if (!EvQueue) + EvQueue = new UchEvtMsgQueue; + UchEventMsg* ev = EvQueue->Get (); + if (ev || ! wait) + return ev; + while (! ev) { + HandleRead (); + ev = EvQueue->Get (); + } + return ev; +} + +/*?nextdoc?*/ +void +UchService :: PutEvent (UchEventMsg* ev) +{ + if (! EvQueue) + EvQueue = new UchEvtMsgQueue; + ev->From = this; + EvQueue->Put (ev); +} + +/*? +These functions are similar to the functions \fun{Put} and \fun{PutBack} +on the event queue of the server. +They create the event queue if it was not set with \fun{SetEvQueue}, +and set the event's server. +?*/ +void +UchService :: PutBackEvent (UchEventMsg* ev) +{ + if (! EvQueue) + EvQueue = new UchEvtMsgQueue; + ev->From = this; + EvQueue->PutBack (ev); +} + + +/*?class UchEventMsg +This class derives from \typ{UchMessage}, so it inherits the usual virtual functions +\fun{ReadFrom} and \fun{WriteTo} that must be redefined in each derived class. +An event is created when a client receives an asynchronous message from its server. +Events are linked together in event queues. +Events must derive from this class. +?*/ + +#ifdef DOC +// fake entries for inline functions + +/*? +Construct an event. +?*/ +UchEventMsg :: UchEventMsg () +{ +} + +#endif /* DOC */ + +/*?nodoc?*/ +UchEventMsg :: ~UchEventMsg () +{ +} + +#ifdef DOC + +/*? +Return the server that sent this event. +The service is known only if the event was appended to the event queue with \fun{UchService::PutEvent}, +else it is 0. +?*/ +UchService* +UchEventMsg :: GetService () +{ +} + +#endif /* DOC */ + +/*?class UchGenEvtMsg +This is a sample derived class of \typ{UchEventMsg}. +It defines events that contain a pointer to a \typ{UchMessage}. +This message must be allocated dynamically because it is deleted by the destructor. + +The virtual functions \fun{ReadFrom} and \fun{WriteTo} are defined to act upon the message stored in the event. + +The following example fetches a word from the input buffer, +creates a message depending on its value +(\typ{FOO_MSG} and \typ{BAR_MSG} have been derived from \typ{UchMessage}), +and transfers the data from the buffer to the event with \fun{Get}. + +This piece of code typically appears in the body +of \fun{NewMessage}: +\begin{ccode} +UchGenEvtMsg* ev = new UchGenEvtMsg; +sword type; +if (! buf.Peek (&type)) + return; +switch (type) { + case Foo : + ev->SetMsg (new FOO_MSG); + break; + case Bar : + ev->SetMsg (new BAR_MSG); + break; + ... +} + +if (!buf.Get (ev)) + // protocol error + +PutEvent (ev); +\end{ccode} +?*/ + +#ifdef DOC + +/*?nextdoc?*/ +UchGenEvtMsg :: UchGenEvtMsg () +{ } + +/*? +Construct a generic event. The second constructor sets its message. +The message is deleted when the event is destroyed. +Thus the message must have been allocated dynamically. +?*/ +UchGenEvtMsg :: UchGenEvtMsg (UchMessage* m) +{ } + +#endif /* DOC */ + +/*?nodoc?*/ +UchGenEvtMsg :: ~UchGenEvtMsg () +{ + if (Msg) + delete Msg; +} + + +#ifdef DOC + +/*?nextdoc?*/ +void +UchGenEvtMsg :: SetMsg (UchMessage* m) +{ } + +/*? +Set and get the message associated to the event. +When setting the value, the previous message of the event (if any) is deleted. +?*/ +UchMessage* +UchGenEvtMsg :: GetMsg () +{ } + +#endif /* DOC */ + +/*?nodoc?*/ +void +UchGenEvtMsg :: ReadFrom (UchMsgBuffer& buf, lword l) +{ + if (Msg) + Msg->ReadFrom (buf, l); +} + +/*?nodoc?*/ +void +UchGenEvtMsg :: WriteTo (UchMsgBuffer& buf) +{ + if (Msg) + Msg->WriteTo (buf); +} + -- cgit v1.1