language-Modula2-0.1: examples/Modula-2_Libraries/PMOS/sources/tests/mboxtest.mod
MODULE MBoxTest;
(********************************************************)
(* *)
(* Test of the mailbox facility *)
(* *)
(* Programmer: P. Moylan *)
(* Last edited: 21 June 1993 *)
(* Status: Working *)
(* *)
(********************************************************)
FROM Mailboxes IMPORT
(* type *) Mailbox,
(* proc *) CreateMailbox, SendMessage, ReceiveMessage;
FROM Windows IMPORT
(* type *) Window, Colour, FrameType, DividerType,
(* proc *) OpenWindow, CloseWindow, WriteString, WriteLn, ReadChar;
FROM Semaphores IMPORT
(* type *) Semaphore,
(* proc *) CreateSemaphore, Wait, Signal;
FROM TaskControl IMPORT
(* proc *) CreateTask;
(************************************************************************)
CONST MessageLimit = 20;
Esc = CHR(27);
TYPE MessageBuffer = ARRAY [0..MessageLimit-1] OF CHAR;
VAR MB: Mailbox;
TaskDone: Semaphore;
(************************************************************************)
PROCEDURE ReadString (w: Window; VAR (*OUT*) buffer: ARRAY OF CHAR;
VAR (*OUT*) length: CARDINAL);
(* Reads a string from the keyboard, and reports its length. *)
(* Returns when a carriage return or escape is read, or if the *)
(* buffer is full. If an escape character is read, the preceding *)
(* input is abandoned and we return with the escape as a *)
(* one-character string. *)
VAR ch: CHAR;
BEGIN
length := 0;
LOOP
ReadChar (w, ch);
IF ch = CHR(13) THEN EXIT(*LOOP*) END(*IF*);
buffer[length] := ch; INC(length);
IF ch = Esc THEN
buffer[0] := Esc; length := 1;
EXIT (*LOOP*);
END(*IF*);
IF length > HIGH(buffer) THEN EXIT(*LOOP*) END(*IF*);
END (*LOOP*);
END ReadString;
(************************************************************************)
PROCEDURE Producer;
VAR w: Window; buffer: MessageBuffer; length: CARDINAL;
BEGIN
OpenWindow (w, blue, cyan, 8, 16, 0, 39, simpleframe, nodivider);
REPEAT
ReadString (w, buffer, length);
IF NOT SendMessage (MB, ADR(buffer), length) THEN
WriteString (w, "Send failure!");
WriteLn (w);
END (*IF*);
UNTIL buffer[0] = Esc;
CloseWindow (w);
Signal (TaskDone);
END Producer;
(************************************************************************)
PROCEDURE Consumer;
VAR w: Window; buffer: MessageBuffer; length: CARDINAL;
BEGIN
OpenWindow (w, white, magenta, 8, 16, 40, 79, simpleframe, nodivider);
LOOP
WriteLn (w);
length := ReceiveMessage (MB, buffer, 5000);
IF length = 0 THEN
WriteString (w, "Empty message received!");
ELSIF buffer[0] = Esc THEN
EXIT (*LOOP*);
END (*IF*);
IF length < MessageLimit THEN
buffer[length] := CHR(0);
END (*IF*);
WriteString (w, buffer);
END (*LOOP*);
CloseWindow (w);
Signal (TaskDone);
END Consumer;
(************************************************************************)
(* MAIN PROGRAM *)
(************************************************************************)
BEGIN
MB := CreateMailbox (MessageLimit);
CreateSemaphore (TaskDone, 0);
CreateTask (Producer, 1, "Producer");
CreateTask (Consumer, 1, "Consumer");
Wait (TaskDone); Wait (TaskDone);
END MBoxTest.