-- Copyright (C) 1983, 1985 by Xerox Corporation. All rights reserved. -- BSPSink.mesa, HGM, 25-Jun-85 3:14:02 -- Please don't forget to update the herald..... DIRECTORY Environment USING [Byte], Event USING [aboutToSwap], EventTypes USING [aboutToBoot, aboutToBootPhysicalVolume], FormSW USING [ AllocateItemDescriptor, newLine, ClientItemsProcType, ProcType, FindItem, Display, CommandItem, BooleanItem], Process USING [Yield], Put USING [Line], Stream USING [Handle, GetBlock, Delete], String USING [AppendChar, AppendString], Supervisor USING [ AddDependency, AgentProcedure, CreateSubsystem, RemoveDependency, SubsystemHandle], Time USING [AppendCurrent], Tool USING [Create, MakeSWsProc, MakeMsgSW, MakeFormSW], ToolWindow USING [TransitionProcType], Window USING [Handle], PupDefs USING [PupPackageMake, PupPackageDestroy, AppendHostName, veryLongWait], PupStream USING [ CreatePupByteStreamListener, DestroyPupListener, RejectThisRequest, StreamClosing, PupListener, PupAddress], PupTypes USING [bspTestSoc], Stats USING [ StatCounterIndex, StatIncr, StatBump, StatsGetCounters, StatsStringToIndex]; BSPSink: MONITOR IMPORTS Event, FormSW, Process, Put, Stream, String, Supervisor, Time, Tool, PupDefs, PupStream, Stats = BEGIN OPEN Stats, PupDefs; statBytesReceived: PUBLIC StatCounterIndex; statConnectionsOpened: PUBLIC StatCounterIndex; stats: POINTER TO ARRAY StatCounterIndex OF LONG CARDINAL ¬ StatsGetCounters[]; useCount: CARDINAL ¬ 0; pleaseStop, running, verbose, superQuiet: BOOLEAN ¬ FALSE; listener: PupStream.PupListener; tool, msg, form: Window.Handle ¬ NIL; broom: Supervisor.SubsystemHandle = Supervisor.CreateSubsystem[Broom]; sinks: CARDINAL ¬ 0; maxSinks: CARDINAL ¬ 4; Init: PROCEDURE = BEGIN herald: STRING = "BSP Sink of 25-Jun-85 3:13:50"L; SetupListenerThings[]; tool ¬ Tool.Create[ name: herald, makeSWsProc: MakeSWs, clientTransition: ClientTransition]; END; SetupListenerThings: PUBLIC PROCEDURE = BEGIN statBytesReceived ¬ StatsStringToIndex["BSP Sink - Bytes received"]; statConnectionsOpened ¬ StatsStringToIndex["BSP Sink - Connections opened"]; END; ListenerOn: PUBLIC PROCEDURE = BEGIN IF (useCount ¬ useCount + 1) = 1 THEN BEGIN Supervisor.AddDependency[client: broom, implementor: Event.aboutToSwap]; running ¬ TRUE; Starter[]; END; UpdatePicture[]; END; Starter: PROCEDURE = BEGIN pleaseStop ¬ FALSE; [] ¬ PupDefs.PupPackageMake[]; listener ¬ PupStream.CreatePupByteStreamListener[ PupTypes.bspTestSoc, Sink, veryLongWait, Check]; END; Check: ENTRY PROCEDURE [who: PupStream.PupAddress] = BEGIN IF sinks >= maxSinks THEN PupStream.RejectThisRequest["Sorry, I'm full now."L]; sinks ¬ sinks + 1; Stats.StatIncr[statConnectionsOpened]; END; ListenerOff: PUBLIC PROCEDURE = BEGIN IF useCount # 0 AND (useCount ¬ useCount - 1) = 0 THEN BEGIN running ¬ FALSE; Stopper[]; Supervisor.RemoveDependency[client: broom, implementor: Event.aboutToSwap]; END; UpdatePicture[]; END; Stopper: PROCEDURE = BEGIN pleaseStop ¬ TRUE; UNTIL sinks = 0 DO Process.Yield[]; ENDLOOP; PupStream.DestroyPupListener[listener]; PupDefs.PupPackageDestroy[]; END; UpdatePicture: PROCEDURE = BEGIN IF form = NIL THEN RETURN; FormSW.FindItem[form, startIX].flags.invisible ¬ running; FormSW.FindItem[form, stopIX].flags.invisible ¬ ~running; FormSW.Display[form]; END; Sink: PROCEDURE [stream: Stream.Handle, who: PupStream.PupAddress] = BEGIN KillSinkLocked: ENTRY PROCEDURE = BEGIN sinks ¬ sinks - 1; END; bytesPerClump: CARDINAL = 512; buffer: PACKED ARRAY [0..bytesPerClump) OF Environment.Byte; bytes: CARDINAL; Announce[who, "Creating"L]; BEGIN ENABLE PupStream.StreamClosing => CONTINUE; UNTIL pleaseStop DO [bytes, ] ¬ Stream.GetBlock[stream, [@buffer, 0, bytesPerClump]]; Stats.StatBump[statBytesReceived, bytes]; ENDLOOP; END; Stream.Delete[stream]; Announce[who, "Destroying"L]; KillSinkLocked[]; END; Announce: PROCEDURE [who: PupStream.PupAddress, arg: STRING] = BEGIN text: STRING = [100]; IF superQuiet THEN RETURN; Time.AppendCurrent[text]; String.AppendString[text, " BSP: "L]; String.AppendString[text, arg]; String.AppendString[text, " BSP connection for "L]; PupDefs.AppendHostName[text, who]; String.AppendChar[text, '.]; IF msg # NIL THEN Put.Line[msg, text]; Put.Line[NIL, text]; END; Start: FormSW.ProcType = BEGIN ListenerOn[]; END; Stop: FormSW.ProcType = BEGIN ListenerOff[]; END; MakeSWs: Tool.MakeSWsProc = BEGIN msg ¬ Tool.MakeMsgSW[window: window, lines: 5]; form ¬ Tool.MakeFormSW[window: window, formProc: MakeForm]; END; startIX: CARDINAL = 0; stopIX: CARDINAL = 1; MakeForm: FormSW.ClientItemsProcType = BEGIN nParams: CARDINAL = 5; items ¬ FormSW.AllocateItemDescriptor[nParams]; items[0] ¬ FormSW.CommandItem[ tag: "Start"L, proc: Start, place: FormSW.newLine, invisible: running]; items[1] ¬ FormSW.CommandItem[ tag: "Stop"L, proc: Stop, place: FormSW.newLine, invisible: ~running]; items[2] ¬ FormSW.BooleanItem[ tag: "Running"L, switch: @running, readOnly: TRUE]; items[3] ¬ FormSW.BooleanItem[tag: "Verbose"L, switch: @verbose]; items[4] ¬ FormSW.BooleanItem[tag: "SuperQuiet"L, switch: @superQuiet]; RETURN[items, TRUE]; END; ClientTransition: ToolWindow.TransitionProcType = BEGIN IF new = inactive THEN msg ¬ form ¬ NIL; END; Broom: Supervisor.AgentProcedure = BEGIN SELECT event FROM EventTypes.aboutToBoot, EventTypes.aboutToBootPhysicalVolume => IF running THEN Stopper[]; ENDCASE => NULL; END; -- initialization Init[]; ListenerOn[]; END.