[MLton] filedes = int (was: Stack size?)

Wesley W. Terpstra wesley@terpstra.ca
Tue, 12 Jul 2005 12:14:05 +0200

On Mon, Jul 11, 2005 at 07:08:19PM -0700, Stephen Weeks wrote:
> > I certainly agree that we don't want to duplicate the code in the
> > libc section of sleep.  I just don't think that there is a good
> > reason to pitch the fractional-second part of the sleep so-called
> > system call.  nanosleep is also in Posix.  I couldn't see what
> > section, but that was enough to tell me that it would be ok to just
> > call nanosleep() (no other computation, just converting the
> > Time.time arg to the struct timespec).
> This makes sense, and weakens my feeling, but I still lean toward
> calling sleep.  I'm interested to hear other opinions.

What I was concerned about is that the method round up.

Right now it is doing a Time.toSecondsroundingfractionsdown.
This means that if I pass in a 'sleep for 0.6s' it doesn't sleep at all.

You could get very bad behaviour from this... imagine the sleep was trying
to avoid some sort of external race condition, like an NFS file lock.

Generally, sleep methods are supposed to sleep _at least_ as long as their
input. If you want to call C's sleep(), fine, but round up. The safe and
sane thing to do is to sleep longer---no one can complain about that.
For proof that this is the convention, I refer you to nanosleep(2) and
usleep(3) which both explicitly state 'at least as long'. Even on windows:
Also note that the description for OS.Process.sleep (which I was talking
about [not Posix.Process.sleep]) says:

sleep t 
	suspends the calling process for the time specified by t. If t is
	zero or negative, then the calling process does not sleep, but
	returns immediately. No exception is raised.

Nowhere here does it anywhere imply anything about seconds, or ignoring
sub-second information, or using libc's sleep(). If anything it implies what
I said, since if it 'suspends the calling process', then it can't return any
sooner than the parameter I gave it. Furthermore, unlike Posix.Proces.sleep
and libc's sleep() there is no return value saying how much time remains,
and therefore no recourse to insure a proper sleep time.

OTOH, I think using nanosleep makes more sense anyways. As a user I
certainly expected the method to honour the parameter I gave it (Time.time),
and even though I am a recovering C programmer I certainly wasn't expecting
it to use libc's sleep method, just to sleep as long as I asked.

With regard to Posix.Process.sleep, I have less of an opinion. Here, it does
return the remaining time, and can be interrupted by a signal. On the one
hand it would be nice if both sleep()s were the same. On the other hand, 
the Posix method claims to be interruptible, which the OS.Process method
does not. I still lean towards nanosleep here, though, simply because the
parameter was a Time.time, not seconds.

So, what I think is proper behaviour:
	In all cases, everywhere in MLton, round timeouts *UP*.
	OS.Process.sleep -- nanosleep() and not interrupted by signals
	Posix.Process.sleep -- nanosleep() and *interruptable* by signals

Wesley W. Terpstra