Re: [racket-dev] sudo make install

2011-01-13 Thread Matthew Flatt
At Wed, 12 Jan 2011 13:57:06 -0700, Jon Rafkind wrote:
 On 01/03/2011 02:11 PM, Matthew Flatt wrote:
  At Mon, 3 Jan 2011 14:55:05 -0500, Sam Tobin-Hochstadt wrote:
  On Mon, Jan 3, 2011 at 2:51 PM, Robby Findler
  ro...@eecs.northwestern.edu wrote:
  Or maybe there is another possible solution that involves changing how
  the distribution and or the docs build works?
  I think the conventional solution is for `make install' to do much
  less work than it current does.  In normal Make-built software,
  `make' does all of the compilation, and `make install' just does the
  copying.  That way, `make install' wouldn't be doing things like
  reading preferences and creating the '.racket' directory.
  Well, moving work from `make install' to `make' does nothing in itself.
  What you're suggesting is that we change what `make install' produces.
 
  In particular, I think you're suggesting that no user-specific actions
  take place as a result of a build and install. That change sounds ok to
  me, and it can be accomplished by passing `--no-user' to `raco setup'
  during `make install'.
 
  Unless anyone objects, I'll push that change soon.
 
 
 Was this change pushed? I did a simple search but didn't find it.

Not until now. I kept looking for our old rationale, but I couldn't
find it and I've given up.

The no-user-setup-on-install default is controlled by `configure', and
there's a new `--enable-usersetup' flag to get the old behavior.

_
  For list-related administrative tasks:
  http://lists.racket-lang.org/listinfo/dev


Re: [racket-dev] raco setup hangs

2011-01-13 Thread Matthew Flatt
This was a bug in the optimizer's tracking of inlining so that it tried
to unroll `loop' forever. It's now fixed.

At Mon, 10 Jan 2011 17:16:45 -0700, Jon Rafkind wrote:
 `raco setup' hangs when it tries to build my planet package. I narrowed
 down the problem to this file
 
 #lang racket/base
 
 (require racket/class)
 
 (define bar
   (mixin () ()
 (define (foo)
   (let loop ([x 0])
 (printf loop!\n)
 (loop (begin
 ;; uncomment for this to fail #;
 (send this anything)
 2))
 
 Put that in bar.rkt or whatever and add it as the main file of info.ss.
 If the line (send this anything) is uncommented then `raco setup' will
 hang. It dosen't print loop! or anything so its not obvious whats
 wrong. `raco make bar.rkt' works though.
 
 I'm not exactly sure when this behavior started occurring but it was
 something like 3 weeks ago.

_
  For list-related administrative tasks:
  http://lists.racket-lang.org/listinfo/dev


Re: [racket-dev] raco setup hangs

2011-01-13 Thread Jon Rafkind
thanks, it works now

On 01/13/2011 01:14 PM, Matthew Flatt wrote:
 This was a bug in the optimizer's tracking of inlining so that it tried
 to unroll `loop' forever. It's now fixed.

 At Mon, 10 Jan 2011 17:16:45 -0700, Jon Rafkind wrote:
 `raco setup' hangs when it tries to build my planet package. I narrowed
 down the problem to this file

 #lang racket/base

 (require racket/class)

 (define bar
   (mixin () ()
 (define (foo)
   (let loop ([x 0])
 (printf loop!\n)
 (loop (begin
 ;; uncomment for this to fail #;
 (send this anything)
 2))

 Put that in bar.rkt or whatever and add it as the main file of info.ss.
 If the line (send this anything) is uncommented then `raco setup' will
 hang. It dosen't print loop! or anything so its not obvious whats
 wrong. `raco make bar.rkt' works though.

 I'm not exactly sure when this behavior started occurring but it was
 something like 3 weeks ago.

_
  For list-related administrative tasks:
  http://lists.racket-lang.org/listinfo/dev


[racket-dev] atomic file update by write rename... not!

2011-01-13 Thread Matthew Flatt
A common trick to atomically update a file x on a Unix filesystem is
to write a file with a temporary name like tmp-x-7687564 (making up a
fresh name each time) in the same directory as x and then use
`rename-or-file-directory' to move tmp-x-7687564 to x.

Unfortunately, this trick does not work for Windows. Don't use it for
anything that needs to be portable.


Here's why the trick works for Unix, at least when there's a single
writer and multiple readers: If any process has x open while it is
being replaced, the process continues to read from the old file, even
though the file doesn't correspond to the file that is named x on the
filesystem. The original file continues to exist until it is closed by
all readers, while new readers of x get the new file. Furthermore,
Unix guarantees that the rename is atomic; there's no time between x
ceasing to refer to the old file and starting to refer to the new file.

There are two problems with this approach under Windows. First, file
rename is not guaranteed to be atomic (although it does seem to be
atomic enough in everything I've tried, for whatever that's worth).
Second, and more significantly in practice, while a file is opened for
reading, you cannot use its name for a new file. You can delete a file
while it's being read, but not only does the deleted file continue to
exist, the delete file's *name* remains occupied until all uses of the
file are closed. So, if x is opened by any readers, you cannot rename
tmp-x-7687564 to x --- not even if you use the flag on the Win32
call to say that it's ok to replace the target file.

Oddly enough, you're allowed to rename a Windows file while it is open.
You can even delete the renamed file and then use the old name for a
new file, even if the original file remains open by a reader who
accessed it by the original name. Unfortunately, that possibility
doesn't help to implement atomic update; if you follow a move x to
old-x-7687564 with a move of tmp-x-7687564 to x, then for a
significant period of time, there would be no x file.

(BTW, I'm not clear on which constraints and behaviors are technically
Windows and which are technically NTFS, but it hardly matters.)


The solution? I haven't been able to find a solution that lets you just
replace `rename-file-or-directory' with something else. The relatively
new support for transactions in NTFS doesn't help unless all I/O is
converted to use transactions, and transaction failures must be handled
explicitly; it's way too painful. The only solutions I can find involve
restructuring programs to add some new kind of synchronization.

To support a parallel build, for example, Kevin had to change `raco
setup' so that multiple processes do not try to compile the same file.
(As it turns out, there were reasons to make the change independent of
problems with atomic update, but the atomic-update problem finally
forced us to make the change.)

We haven't yet fixed the preferences file. I'll post a separate message
on that one.

Is there anything else in the main distribution that is uses
`rename-file-or-directory' for atomic update?
_
  For list-related administrative tasks:
  http://lists.racket-lang.org/listinfo/dev


Re: [racket-dev] atomic file update by write rename... not!

2011-01-13 Thread Eli Barzilay
15 minutes ago, Matthew Flatt wrote:
 Is there anything else in the main distribution that is uses
 `rename-file-or-directory' for atomic update?

Is the handin-server's use kosher?  There are three uses of it, and
the only one that looks suspicious is the last one, where ATTEMPT is
renamed to SUCCESS-0.

-- 
  ((lambda (x) (x x)) (lambda (x) (x x)))  Eli Barzilay:
http://barzilay.org/   Maze is Life!
_
  For list-related administrative tasks:
  http://lists.racket-lang.org/listinfo/dev


Re: [racket-dev] atomic file update by write rename... not!

2011-01-13 Thread Matthew Flatt
At Thu, 13 Jan 2011 16:30:08 -0500, Eli Barzilay wrote:
 15 minutes ago, Matthew Flatt wrote:
  Is there anything else in the main distribution that is uses
  `rename-file-or-directory' for atomic update?
 
 Is the handin-server's use kosher?  There are three uses of it, and
 the only one that looks suspicious is the last one, where ATTEMPT is
 renamed to SUCCESS-0.

Those are directories, and you can't move to an existing directory name
on any platform, right?

I think the handin server probably depends on non-concurrent handins
for a given account, though, since it shuffles many files and
directories around. Probably it should use some sort of lock to enforce
non-concurrency.

_
  For list-related administrative tasks:
  http://lists.racket-lang.org/listinfo/dev


Re: [racket-dev] atomic file update by write rename... not!

2011-01-13 Thread Robby Findler
On Thu, Jan 13, 2011 at 3:40 PM, Matthew Flatt mfl...@cs.utah.edu wrote:
 At Thu, 13 Jan 2011 16:30:08 -0500, Eli Barzilay wrote:
 15 minutes ago, Matthew Flatt wrote:
  Is there anything else in the main distribution that is uses
  `rename-file-or-directory' for atomic update?

 Is the handin-server's use kosher?  There are three uses of it, and
 the only one that looks suspicious is the last one, where ATTEMPT is
 renamed to SUCCESS-0.

 Those are directories, and you can't move to an existing directory name
 on any platform, right?

 I think the handin server probably depends on non-concurrent handins
 for a given account, though, since it shuffles many files and
 directories around. Probably it should use some sort of lock to enforce
 non-concurrency.

In general, it seems like the handin server can safely make the
assumption that there is only one sever running for a given directory
and thus can do all of the syncronization at the Racket level (unlike
the preferences file).

Hopefully the preferences file is the only place (and things like raco
setup where we know we're creating lots of processes).

Robby
_
  For list-related administrative tasks:
  http://lists.racket-lang.org/listinfo/dev

[racket-dev] the preferences file under Windows

2011-01-13 Thread Matthew Flatt
Currently, the `get-preference' and `put-preferences' functions from
`racket/file' (which are used by DrRacket and other Racket tools) use
the write-to-temp-file-and-rename approach to atomic file update.
There's a lock to keep multiple writers from trying to update the file,
but no lock for readers.

As explained in my previous message, that doesn't work for Windows.


The writer lock is implemented by the existence of a lock file. That
is, a writer cannot proceed unless it is able to create the lock file,
and if some other process has created the lock file, then creation of
the lock file by other processes fails (so they know that the file is
locked). That much seems fine for Windows. The problem under Windows is
to prevent readers from interfering with a writer --- since having a
file open to read interferes with update --- the same as other writers.


Option 1: Readers could take the lock on the preferences file in the
 same way as writers.

The drawback of this option is that readers need write access to the
directory containing the preferences file, since the lock is
implemented by creating a file. Does that matter? It sounds wrong to
me, but maybe it's just fine.


Option 2: Use Windows file locking, and pick a new name for the
 preferences file under Windows.

It takes a few steps to explain the new-name part...

Not coincidentally, I recently added `port-try-file-lock?' and
`port-file-unlock' to Racket, so OS-supported file locking is an
option. (An evt form for locks would be nice, but OS APIs for file
locking make that difficult or impossible.)

Unfortunately, you can only hold the lock on a file if the file is open
--- and having the preferences file open is the root of the problem for
moving a new file into place. You can write to a file while holding a
lock, of course, but writing directly to the data file risks losing
information if the write is interrupted.

We could solve this sub-problem by having two files: the first holds
the preferences content, and the second exists only to be locked and
unlocked. That way, holding a lock doesn't interfere with replacing the
data file.

Unfortunately (again), the lock file has to exist alongside the data
file, and our existing preferences files are not accompanied by lock
files. It's no good assuming that you don't need the lock if there's no
lock file present, because the lock file might get created in between
the time that you try to use the lock file and the time that you try to
open the preferences file.

That's why this option includes picking a new name for the preferences
file (and its accompanying lock file) under Windows. The existing
preferences file would be used as a read-only fallback when no file
exists with the new preferences-file name.


Any opinions? Or does anyone see other options?

_
  For list-related administrative tasks:
  http://lists.racket-lang.org/listinfo/dev


Re: [racket-dev] the preferences file under Windows

2011-01-13 Thread Eli Barzilay
30 minutes ago, Matthew Flatt wrote:
 
 Unfortunately (again), the lock file has to exist alongside the data
 file, and our existing preferences files are not accompanied by lock
 files. It's no good assuming that you don't need the lock if there's
 no lock file present, because the lock file might get created in
 between the time that you try to use the lock file and the time that
 you try to open the preferences file.

Why not always use such a lock file, creating it if it's not there --
and then you can open it once per process, and lock/unlock it for each
read/write of the actual file.  Does this fail somehow?

-- 
  ((lambda (x) (x x)) (lambda (x) (x x)))  Eli Barzilay:
http://barzilay.org/   Maze is Life!
_
  For list-related administrative tasks:
  http://lists.racket-lang.org/listinfo/dev


Re: [racket-dev] the preferences file under Windows

2011-01-13 Thread Matthew Flatt
At Thu, 13 Jan 2011 17:29:15 -0500, Eli Barzilay wrote:
 30 minutes ago, Matthew Flatt wrote:
  
  Unfortunately (again), the lock file has to exist alongside the data
  file, and our existing preferences files are not accompanied by lock
  files. It's no good assuming that you don't need the lock if there's
  no lock file present, because the lock file might get created in
  between the time that you try to use the lock file and the time that
  you try to open the preferences file.
 
 Why not always use such a lock file, creating it if it's not there --
 and then you can open it once per process, and lock/unlock it for each
 read/write of the actual file.  Does this fail somehow?

That's a good idea. It's a little bit of option 1, in that a reader
will sometimes need to write a file --- but only in the transitional
case of dealing with an existing preference file without a lock file.
_
  For list-related administrative tasks:
  http://lists.racket-lang.org/listinfo/dev


Re: [racket-dev] the preferences file under Windows

2011-01-13 Thread Eli Barzilay
Two minutes ago, Matthew Flatt wrote:
 At Thu, 13 Jan 2011 17:29:15 -0500, Eli Barzilay wrote:
  30 minutes ago, Matthew Flatt wrote:
   
   Unfortunately (again), the lock file has to exist alongside the
   data file, and our existing preferences files are not
   accompanied by lock files. It's no good assuming that you don't
   need the lock if there's no lock file present, because the lock
   file might get created in between the time that you try to use
   the lock file and the time that you try to open the preferences
   file.
  
  Why not always use such a lock file, creating it if it's not there
  -- and then you can open it once per process, and lock/unlock it
  for each read/write of the actual file.  Does this fail somehow?
 
 That's a good idea. It's a little bit of option 1, in that a reader
 will sometimes need to write a file --- but only in the transitional
 case of dealing with an existing preference file without a lock
 file.

Yeah...  If it wasn't for the transition, it would have already been
there (created when the prefs file is created).

(Another point is where the lock file is located, like putting it in
some /dev/shm-like place so the file itself becomes just a way to name
a kernel lock.  I think that I've seen that discussed in some linux
context, with a similar sounding locking scheme (where you open the
file and then lock it).)

-- 
  ((lambda (x) (x x)) (lambda (x) (x x)))  Eli Barzilay:
http://barzilay.org/   Maze is Life!
_
  For list-related administrative tasks:
  http://lists.racket-lang.org/listinfo/dev


Re: [racket-dev] the preferences file under Windows

2011-01-13 Thread Robby Findler
On Thu, Jan 13, 2011 at 4:36 PM, Matthew Flatt mfl...@cs.utah.edu wrote:
 At Thu, 13 Jan 2011 17:29:15 -0500, Eli Barzilay wrote:
 30 minutes ago, Matthew Flatt wrote:
 
  Unfortunately (again), the lock file has to exist alongside the data
  file, and our existing preferences files are not accompanied by lock
  files. It's no good assuming that you don't need the lock if there's
  no lock file present, because the lock file might get created in
  between the time that you try to use the lock file and the time that
  you try to open the preferences file.

 Why not always use such a lock file, creating it if it's not there --
 and then you can open it once per process, and lock/unlock it for each
 read/write of the actual file.  Does this fail somehow?

 That's a good idea. It's a little bit of option 1, in that a reader
 will sometimes need to write a file --- but only in the transitional
 case of dealing with an existing preference file without a lock file.

Also, I think we would have had to do that regardless, unless we
wanted the installation process to create the lockfile or something.

Robby
_
  For list-related administrative tasks:
  http://lists.racket-lang.org/listinfo/dev

Re: [racket-dev] the preferences file under Windows

2011-01-13 Thread Robby Findler
On Thu, Jan 13, 2011 at 4:42 PM, Eli Barzilay e...@barzilay.org wrote:
 Two minutes ago, Matthew Flatt wrote:
 At Thu, 13 Jan 2011 17:29:15 -0500, Eli Barzilay wrote:
  30 minutes ago, Matthew Flatt wrote:
  
   Unfortunately (again), the lock file has to exist alongside the
   data file, and our existing preferences files are not
   accompanied by lock files. It's no good assuming that you don't
   need the lock if there's no lock file present, because the lock
   file might get created in between the time that you try to use
   the lock file and the time that you try to open the preferences
   file.
 
  Why not always use such a lock file, creating it if it's not there
  -- and then you can open it once per process, and lock/unlock it
  for each read/write of the actual file.  Does this fail somehow?

 That's a good idea. It's a little bit of option 1, in that a reader
 will sometimes need to write a file --- but only in the transitional
 case of dealing with an existing preference file without a lock
 file.

 Yeah...  If it wasn't for the transition, it would have already been
 there (created when the prefs file is created).

 (Another point is where the lock file is located, like putting it in
 some /dev/shm-like place so the file itself becomes just a way to name
 a kernel lock.  I think that I've seen that discussed in some linux
 context, with a similar sounding locking scheme (where you open the
 file and then lock it).)

Don't we only need this under windows?

Robby
_
  For list-related administrative tasks:
  http://lists.racket-lang.org/listinfo/dev