summaryrefslogtreecommitdiff
path: root/comm/OLD/Service.cc
diff options
context:
space:
mode:
authorchatty1993-04-07 11:50:31 +0000
committerchatty1993-04-07 11:50:31 +0000
commitba066c34dde204aa192d03a23a81356374d93731 (patch)
tree39391f6235d2cf8a59a0634ac5ea430cdd21f5d4 /comm/OLD/Service.cc
parent05ab076e1c2a9ca16472f9a6b47b8d22914b3783 (diff)
downloadivy-league-ba066c34dde204aa192d03a23a81356374d93731.zip
ivy-league-ba066c34dde204aa192d03a23a81356374d93731.tar.gz
ivy-league-ba066c34dde204aa192d03a23a81356374d93731.tar.bz2
ivy-league-ba066c34dde204aa192d03a23a81356374d93731.tar.xz
Initial revision
Diffstat (limited to 'comm/OLD/Service.cc')
-rw-r--r--comm/OLD/Service.cc328
1 files changed, 328 insertions, 0 deletions
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);
+}
+