[Cuis-dev] Questions triggered by #forceChangesToDisk

Phil B pbpublist at gmail.com
Mon Sep 16 23:10:59 PDT 2019


Andres,

On Mon, Sep 16, 2019 at 10:32 PM Andres Valloud via Cuis-dev <
cuis-dev at lists.cuis.st> wrote:

> Phil,
>
> Regarding your observations on forceChangesToDisk, first a side comment.
>   That there is a method or even a primitive called
> 'blah-blah-flush-blah' does not mean the function fflush()
>
> https://pubs.opengroup.org/onlinepubs/9699919799/functions/fflush.html
>
> or equivalent is actually called.


Good point.  Just because it seems logical that's what it would/should be
doing doesn't constitute proof.  So let's start with a sanity check:

Running a recent 64-bit spur image on Linux, I apply updates to get to
3878, fire up the image and open a Workspace in which I run in sequence:

f:='flushtest.txt' asFileEntry .
ws:=f writeStream. "this gets us a 0 byte file"
ws class. "StandardFileStream"
ws nextPutAll: 'this is a test'. "still 0 bytes... it's in the buffer as
expected"
ws flush. "14-byte file and the contents are as expected... looks good"

I feel better: flush is flushing... now let's look at how.


>   Assuming otherwise eventually leads
> to conclusions such as "xyzOS is so broken haha", and that's really self
> limiting.
>

Fair enough.


> So, with a skeptic mentality in place, what is that flush method
> actually doing?


Taking a half step back, I ask the question: what's it supposed to be
doing?  According to
https://github.com/Geal/Squeak-VM/blob/master/platforms/Mac%20OS/vm/Documentation/3.2.2%20Release%20Notes.rtf
the file flush primitive was added in (classic) VM 3.0.5 and 'now actually
flushes the file via an OS call' as of 3.0.6.  So that gives an indication
that it at least *should* correspond to something at the OS level rather
than a home grown approximation of flush.  OK, back to our regularly
scheduled programming...


>   It looks like the relevant code is this:


> primFlush: id
>         "Flush pending changes to the disk"
>         | p |
>         <primitive: 'primitiveFileFlush' module: 'FilePlugin'>
>         "In some OS's seeking to 0 and back will do a flush"
>         p _ self position.
>         self position: 0; position: p


> That primitive failure is strange indeed, plus the failure is silent so
> good luck noticing something might be off.  So, rather than seeking back
> and forth to (pretend to) deal with the failure, the question should be
> why fflush() can't do its job.


Intrigued, I proceed to open a VMMaker image...


>   Does primitiveFileFlush actually call
> the equivalent of fflush() in all platforms?


When I look at FilePlugin>>primitiveFileFlush it calls sqFileFlush: with
the file as a parameter.  Just one problem: the only implementor I can find
is FileSimulatorPlugin which in turn just sends #flush which gets us right
back to #primitiveFileFlush (and besides we're not running in the simulator
so this isn't applicable)  Not finding anything else interesting in the
image, I grep the VM source tree and find sqFileFlush in:
platforms/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c (which calls
fflush(getFile(f)) and has an interesting comment[1])
platforms/win32/plugins/FilePlugin/sqWin32FilePrims.c (which
calls FlushFileBuffers(FILE_HANDLE(f)) and ignores the return code)

[1] "fflush() can fail for the same reasons write() can so errors must be
checked but sqFileFlush() must support being called on readonly files for
historical reasons so EBADF is ignored"... so there's one example of how it
could fail but for this particular failure case it is ignored in the C code

  Where and why does the
> primitive fail, exactly?


It looks like it will never fail on Windows (regardless of the fact that
the call might have) but can fail everywhere else depending on the rules of
the particular OS.  On Linux, over a dozen possible error codes are given
(one of them is the ignored EBADF case) as well as a note that a variety of
additional errors can occur depending on the particular object the file
descriptor represents.  So reasons: many.

  Suppose the id is stale, why does changing the
> file position improve the situation on an file that is not open?  Does
> the primitive fail because it's not implemented?  If that happens, then
> why isn't the hack of opening / closing the file done here instead,
> i.e.: why is there yet another hack that is different?


Good questions and I could only speculate as to the answers.


>   Or, why was it
> necessary to hack forceChangesToDisk, in a different way, on top of the
> hack here?


I believe the #forceChangesToDisk hack had a different objective.  The
other hack(s) are dealing with flush failure, #forceChangesToDisk appears
to predate flush support and/or to deal with the reality at the time that
flush alone often wasn't a complete solution.


>   Exactly what operating systems are those "some OS's" the
> comment talks about?


I'm as baffled by that cryptic comment as you.  I did a quick search on the
text of the comment and found
http://forum.world.st/The-Inbox-Files-monty-172-mcz-td4950635.html which
seems to agree that there's a problem in silently ignoring the error.


>   Is there any evidence in support of the
> authoritative assertion that seeking causes flushing?
>

I did a little more general search trying to find something, anything that
might point in a direction that leads to clarity... nothing so far.


>
> Andres.
> --
> Cuis-dev mailing list
> Cuis-dev at lists.cuis.st
> https://lists.cuis.st/mailman/listinfo/cuis-dev


Thanks,
Phil
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.cuis.st/mailman/archives/cuis-dev/attachments/20190917/1aa0cc69/attachment-0001.htm>


More information about the Cuis-dev mailing list