<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=iso-8859-15">
<META content="MSHTML 6.00.6000.16587" name=GENERATOR></HEAD>
<BODY style="MARGIN: 4px 4px 1px; FONT: 10pt Tahoma">
<DIV>Mika:</DIV>
<DIV> </DIV>
<DIV>I've used pickles between various platforms in the past.  I use the Pickle2 variant.</DIV>
<DIV> </DIV>
<DIV>In my code, I've registered special picklers to deal with mutexes.  Since it doesn't make sense to transfer the state of a mutex between computers, I simply recreate/reinitialize the mutex on the receiving computer.  Here is an example of an interface and a module that defines a type ServerConfig.T that I transfer between computers using Pickle2 and network objects.  I've omitted some of the detail just to show the important stuff about the special pickling definitions and procedures:</DIV>
<DIV> </DIV>
<DIV><FONT face="Courier New"></FONT> </DIV>
<DIV><FONT face="Courier New">INTERFACE ServerConfig;</FONT></DIV>
<DIV><FONT face="Courier New"></FONT> </DIV>
<DIV><FONT face="Courier New">CONST<BR>   Brand = "ServerConfig"; (* prefix for all branded references *)<BR></FONT></DIV>
<DIV><FONT face="Courier New">TYPE<BR>   T <: Public;</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face="Courier New">   Public = ConfigSettings.T OBJECT<BR>   METHODS<BR>      init (): T;<BR>      (* initialize to default settings *)</FONT></DIV>
<DIV><FONT face="Courier New">      ...</FONT></DIV>
<DIV><FONT face="Courier New">   END; (* Public *)</FONT></DIV>
<DIV><FONT face="Courier New">END ServerConfig.</FONT></DIV>
<DIV><FONT face="Courier New"></FONT> </DIV>
<DIV><FONT face="Courier New"> </DIV>
<DIV><BR></DIV></FONT>
<DIV><FONT face="Courier New">MODULE ServerConfig EXPORTS ServerConfig;</FONT></DIV>
<DIV><FONT face="Courier New"></FONT> </DIV>
<DIV><FONT face="Courier New">IMPORT</FONT></DIV>
<DIV><FONT face="Courier New">   Pickle2 AS Pickle;<BR></DIV></FONT>
<DIV><FONT face="Courier New">TYPE<BR>   PrivateMutex = MUTEX BRANDED Brand & ".PrivateMutex" OBJECT END;<BR></DIV></FONT><FONT face="Courier New">
<DIV><FONT face="Courier New">REVEAL<BR></FONT><FONT face="Courier New">   T = Public BRANDED Brand & ".T" OBJECT<BR>      mutex: PrivateMutex := NIL;<BR>      ...<BR>   METHODS<BR>   OVERRIDES<BR>      init := Init;</FONT></DIV>
<DIV><FONT face="Courier New">      ...</FONT></DIV>
<DIV><FONT face="Courier New">   END; (* T *)<BR></FONT></DIV>
<DIV> </DIV>
<DIV>(*-------------------*)<BR>(* Pickle Procedures *)<BR>(*-------------------*)</FONT></DIV>
<DIV><FONT face="Courier New"></FONT> </DIV>
<DIV><FONT face="Courier New">TYPE<BR>   Special = Pickle.Special OBJECT<BR>   OVERRIDES<BR>      write := WriteSpecial;<BR>      read := ReadSpecial;<BR>   END; (* Special *)</FONT></DIV>
<DIV><FONT face="Courier New"></FONT> </DIV>
<DIV><FONT face="Courier New">PROCEDURE WriteSpecial (self: Special;<BR>                        <*UNUSED*>ref: REFANY;<BR>                        <*UNUSED*>writer: Pickle.Writer<BR>                       )<BR>   RAISES {Pickle.Error,<BR>      <*NOWARN*>Wr.Failure, Thread.Alerted} =<BR>(* Special pickle writer for ServerConfig.PrivateMutex objects. *)<BR>BEGIN (* WriteSpecial *)<BR>   IF self.sc = TYPECODE(PrivateMutex)<BR>   THEN<BR>      (* omit writing the mutex field *)<BR>   ELSE<BR>      RAISE Pickle.Error("ServerConfig.WriteSpecial asked to process unrecognized typecode."); (* should never happen *)<BR>   END; (* if *)<BR>END WriteSpecial;</FONT></DIV>
<DIV><FONT face="Courier New"></FONT> </DIV>
<DIV><FONT face="Courier New"></FONT> </DIV>
<DIV><FONT face="Courier New"></FONT> </DIV>
<DIV><FONT face="Courier New">PROCEDURE ReadSpecial (self: Special;<BR>                       reader: Pickle.Reader;<BR>                       id: Pickle.RefID<BR>                      ): REFANY<BR>   RAISES {Pickle.Error,<BR>      <*NOWARN*>Rd.EndOfFile, Rd.Failure, Thread.Alerted} =<BR>(* Special pickle reader for ServerConfig.PrivateMutex objects. *)<BR>BEGIN (* ReadSpecial *)<BR>   IF self.sc = TYPECODE(PrivateMutex)<BR>   THEN<BR>      WITH m = NEW(PrivateMutex)<BR>      DO<BR>         reader.noteRef(m, id);<BR>         RETURN m;<BR>      END; (* with *)<BR>   ELSE<BR>      RAISE Pickle.Error("ServerConfig.ReadSpecial asked to process unrecognized typecode."); (* should never happen *)<BR>   END; (* if *)<BR>END ReadSpecial;</FONT></DIV>
<DIV><FONT face="Courier New"></FONT> </DIV>
<DIV><FONT face="Courier New"></FONT> </DIV>
<DIV><FONT face="Courier New"></FONT> </DIV>
<DIV><FONT face="Courier New">BEGIN (* ServerConfig module initialization *)<BR>   Pickle.RegisterSpecial(NEW(Special, sc := TYPECODE(PrivateMutex)));<BR>END ServerConfig.</FONT><BR><BR>Regards,</DIV>
<DIV>Randy</DIV>
<DIV><BR>>>> Mika Nystrom <mika@async.caltech.edu> 1/16/2008 3:45 AM >>><BR><BR>Can I add something tricky to a wish list on regression testing?<BR>Tricky because I don't know the best way to go about it.<BR><BR>I have spent quite some time with various versions of Modula-3<BR>tracking down issues with Pickles.  Usually the problem is that<BR>Pickles aren't transferrable between systems, and it turns out that<BR>I have included some type, somewhere, that doesn't translate.<BR>MUTEX is a good example.  First of all it would be very nice if<BR>such system dependencies were kept out (for instance, don't know<BR>if it's possible, but something like this...)<BR><BR>TYPE RealMutex = OBJECT END;<BR><BR>TYPE WinMutex = RealMutex OBJECT (* windows fields *) END;<BR>TYPE PosixMutex = RealMutex OBJECT (* POSIX fields *) END;<BR><BR>TYPE MUTEX = RealMutex;<BR><BR>and of course all that a client sees is MUTEX which is the same<BR>across systems.<BR><BR>However I realize that what I say above may not be possible or<BR>practical in all cases.<BR><BR>This brings me to the fact that Pickles are sensitive to certain<BR>types of bugs (I think), and it would be very nice to check that<BR>all OS/processor builds of M3 make compatible Pickles, with the<BR>possible exception of things like MUTEX.  Of course this can't be<BR>done within a single build...<BR><BR>     Mika<BR><BR></DIV></BODY></HTML>