-- File: BSPSink.mesa, Last Edit: September 22, 1980 12:56 PM -- Please don't forget to update the herald..... DIRECTORY Process USING [Yield], Stream USING [Handle, GetBlock, Delete], String USING [AppendChar, AppendString], Time USING [AppendCurrent], Event USING [Item, Reason, AddNotifier], FormSW USING [ AllocateItemDescriptor, newLine, ClientItemsProcType, ProcType, FindItem, Display, CommandItem, BooleanItem], Put USING [Line], Tool USING [Create, MakeSWsProc, MakeMsgSW, MakeFormSW], ToolWindow USING [TransitionProcType], Window USING [Handle], StatsDefs USING [ StatCounterIndex, StatIncr, StatBump, StatsGetCounters, StatsStringToIndex], PupStream USING [ CreatePupByteStreamListener, DestroyPupListener, RejectThisRequest, StreamClosing, PupListener, PupAddress], PupDefs USING [PupPackageMake, PupPackageDestroy, AppendHostName, veryLongWait], PupTypes USING [bspTestSoc]; BSPSink: MONITOR IMPORTS Process, Stream, String, Time, Event, FormSW, Put, Tool, StatsDefs, PupStream, PupDefs = BEGIN OPEN StatsDefs, PupDefs; herald: STRING = "BSP Sink of September 22, 1980"; 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; eventItem: Event.Item _ [eventMask: 177777B, eventProc: Broom]; sinks: CARDINAL _ 0; maxSinks: CARDINAL _ 4; 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 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; StatsDefs.StatIncr[statConnectionsOpened]; END; ListenerOff: PUBLIC PROCEDURE = BEGIN IF useCount # 0 AND (useCount _ useCount - 1) = 0 THEN BEGIN running _ FALSE; Stopper[]; 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; buffer: ARRAY [0..256) OF WORD; bytes: CARDINAL; Announce[who, "Creating"L]; BEGIN ENABLE PupStream.StreamClosing => CONTINUE; UNTIL pleaseStop DO [bytes, ] _ Stream.GetBlock[stream, [@buffer, 0, 512]]; StatsDefs.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: PROCEDURE [why: Event.Reason] = BEGIN SELECT why FROM makeImage, makeCheck => IF running THEN Stopper[]; startImage, restartCheck, continueCheck => IF running THEN Starter[]; ENDCASE => NULL; END; -- initialization SetupListenerThings[]; tool _ Tool.Create[ name: herald, makeSWsProc: MakeSWs, clientTransition: ClientTransition]; Event.AddNotifier[@eventItem]; ListenerOn[]; END.