(* 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</TT> (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;

TYPE
  Public = StableData.Public BRANDED OBJECT
        nm         : Pathname.T;
        log        : Wr.T;
        lm         : LogManager.T := NIL;
        forceToDisk: BOOLEAN;
      METHODS
        replayLog(log: Rd.T);
      OVERRIDES
        init            := Init;
        dispose         := Dispose;
        flushLog        := FlushLog;
        freeLog         := FreeLog;
        writeCheckpoint := WriteCheckpoint;
        readCheckpoint  := ReadCheckpoint;
      END;

(* <H3> Implementations of "Stable.ig"-methods </H3> *)

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};

(* <H3> Procedures to be called from the generated code </H3> *)

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.



