[racket] flock() stops racket-5.1.1 build on Solaris x86
At Mon, 23 May 2011 12:52:12 +0100, Tim Brown wrote:
> My never ending battle to get racket to play nice with Solaris continues:
> [...]
> STREAMS and STREAM fds on Solaris use fcntl(F_GETLK/F_SETLK, F_SETLKW)
> and their 64-bit counterparts F_GETLK64 etc. However, these need a pointer
> to a lock structure to be managed/associated with the fd, and I'm not sure
> what the best means to do this would be (there seems to be a neat solution
> to a lot of the things in racket -- best left to the authors IMHO).
I don't think the OS holds onto the struct provided with F_SETLK
(because that's not the sort of thing that a Unix would do); it copies
the information out. But...
> Solaris seems to take quite a dim view of flock(); from man flock():
> > NOTES
> > Use of these interfaces should be restricted to only appli-
> > cations written on BSD platforms. Use of these interfaces
> > with any of the system libraries or in multi-thread applica-
> > tions is unsupported.
> [...]
> But is there any chance of a proper fcntl-based solution, then that would
> be appreciated.
That's nothing compared to the dim view of F_SETLK in the BSD world.
The BSD-derived Mac OS X man page puts it this way:
This interface follows the completely stupid semantics of System V and
IEEE Std 1003.1-1988 (``POSIX.1'') that require that all locks associated
with a file for a given process are removed when any file descriptor for
that file is closed by that process. This semantic means that applica-
tions must be aware of any files that a subroutine library may access.
For example if an application for updating the password file locks the
password file database while making the update, and then calls
getpwname(3) to retrieve a record, the lock will be lost because
getpwname(3) opens, reads, and closes the password database. The data-
base close will release all locks that the process has associated with
the database, even if the library routine never requested a lock on the
database.
>From a Racket implementor's perspective, the BSD side has it right.
It's not just subroutines within Racket, but different threads within a
single Racket process that might compete for a file lock; when a thread
fails to obtain a lock and closes a file, any thread in the same OS
process that held the lock immediately loses it.
I don't see an easy way around the problem. Your patch to make file
locks unsupported looks like the right one for now.