Copyright (C) 1994, Digital Equipment Corporation           
 All rights reserved.                                        
 See the file COPYRIGHT for a full description.              
 Created by Carsten Weich                                    
 Last modified on Thu Jan 19 13:14:02 PST 1995 by kalsow     
      modified on Wed Jan 11 17:56:09 PST 1995 by chaiken    
      modified on Tue Sep 27 11:37:33 PDT 1994 by weich      

The generic module StableRep provides the part of the implementation of stable objects Stable.T that is independent of {\tt Data.T} (see Stable.ig for a description of the methods). It is not intended that any client calls anything in this interface directly. Only the generated code references this interface.

This code is used by the code generated by stablegen. It contains everything of the generated stable implementation that does not need to be generated by stablegen. However, it has to be generic because there are fields and a method added to the user object which are referencend in this module.

The method unspoolLog is added. The method is generated by stablegen and is called by Recover(). It reads the log and calls every method recorded on it.

GENERIC INTERFACE StableRep(StableData);

IMPORT StableError, StableLog, LogManager, Pathname;
IMPORT OSError, Wr, Rd;

REVEAL StableData.T <: Public;

  Public = StableData.Public BRANDED OBJECT
        nm         : Pathname.T;
        log        : Wr.T;
        lm         : LogManager.T := NIL;
        forceToDisk: BOOLEAN;
        replayLog(log: Rd.T);
        init            := Init;
        dispose         := Dispose;
        flushLog        := FlushLog;
        freeLog         := FreeLog;
        writeCheckpoint := WriteCheckpoint;
        readCheckpoint  := ReadCheckpoint;
\subsubsection*{Implementations of Stable.ig-methods}

PROCEDURE Init (    self       : Public;
                    dir        : Pathname.T;
                VAR recovered  : BOOLEAN;
                    forceToDisk               := TRUE;
                    lm         : LogManager.T := NIL   )
  : StableData.T
  RAISES {StableError.E};

PROCEDURE Dispose (self: Public) RAISES {StableError.E};

PROCEDURE FlushLog (self: Public) RAISES {StableError.E};
PROCEDURE FreeLog (self: Public) RAISES {StableError.E};

PROCEDURE ReadCheckpoint (self: Public;
                                     cp  : Rd.T          )
  : StableData.T
  RAISES {StableError.E};
PROCEDURE WriteCheckpoint (self: Public; wr: Wr.T)
  RAISES {StableError.E};
\subsubsection*{Procedures to be called from the generated code}

PROCEDURE Recover (t: StableData.T): StableData.T
  RAISES {StableError.E, StableLog.Error, OSError.E};
Do the recovery: Only called if t.lm.recoverable() has returned TRUE. The procedure follows the protocol described in LogManager.i3 to read in the latest checkpoint. Then it will read the log if necessary by calling t.replayLog().
PROCEDURE Checkpoint (t: StableData.T)
  RAISES {StableError.E};
Write a checkpoint following the protocoll described in LogManager.i3

PROCEDURE ReOpenLog (self: StableData.T);
Used by the generated code to open the log: The procedure tests whether the log is already opened for writing and reopens it (using the log manager object) if not. In case of an exception, it will halt (StableError.Halt).
END StableRep.