Is a Java FileLock a POSIX advisory (fcntl) lock
Asked Answered
S

2

5

I have a C++ program that locks files using POSIX advisory locks. That is, it uses the POSIX fcntl system call for lock operations. I want a Java program to interoperate with that C++ program, so I want my Java program to also use POSIX advisory locks. File locking in Java should use the standard FileLock class. But the API documentation is understandably vague on just how locking is implemented:

This file-locking API is intended to map directly to the native locking facility of the underlying operating system. Thus the locks held on a file should be visible to all programs that have access to the file, regardless of the language in which those programs are written.

If I am running a common implementation of Java (Oracles, Open JDK) on a POSIX operating system, or more specifically a GNU/Linux system, is it safe to assume that the Java FileLock class uses POSIX advisory locks?

Sorcim answered 9/5, 2014 at 10:30 Comment(8)
What choice does it have?Panel
@EJP The alternative would be to use a BSD flock system call. Which might or might not be implemented using fcntl.Sorcim
@EJP ... but looking more closely, I see that flock does not support record-level locking.Sorcim
Also "The flock(), fcntl(2), and lockf(3) locks are compatible". So there's nothing left for this question to be about.Panel
Unless something has recently changed flock is incompatible with fcntl (and lockf) on Linux. The two are essentially invisible to one another. So there is indeed a point to this question.Nordin
(OReilly, Understanding the Linux Kernel, 3ed, 2005: "Both the fcntl() and the flock() system call may be used on the same file at the same time, but a file locked through fcntl() does not appear locked to flock(), and vice versa. This has been done on purpose in order to avoid the deadlocks occurring when an application using a type of lock relies on a library that uses the other type."Nordin
OReilly, Understanding the Linux Kernel, 2nd, sec 12.7: A lock produced by fcntl() is of type FL_POSIX, while a lock produced by flock() is of type FL_FLOCK, FL_MAND (for share-mode locks), or FL_LEASE (for leases). The types of locks produced by fcntl() may safely coexist with those produced by flock(), but neither one has any effect on the other. Therefore, a file locked through fcntl() does not appear locked to flock(), and vice versa.Nordin
To complicate matters further, there is work on a new type of lock, file-private POSIX locks: lwn.net/Articles/586904Open
S
5

Some Unix operating systems, including Linux, provide BSD-style (flock) locks, so it might be thought that Java FileLock could be implemented using BSD-style locks rather than POSIX locks. But that is not possible, because BSD-style locks are whole-file locks rather than record locks, and FileLock is a record lock: each lock is for a range of bytes in a file. Thus there is no real choice on a Unix system, and assuming that the implementation of FileLock uses POSIX fcntl locks is a safe assumption on a Unix operating system.

The resulting FileLock locks might or might not interact with BSD-style locks. BSD-style locks can be implemented using POSIX locks (this was the case for Linux before version 2.0), or the operating system might have the two styles of locking interact (this is the case for FreeBSD). But in general that can not be guaranteed, and BSD-style locks and Java locks might be effectively invisible to each other (this is the case for any version of Linux you are likely to encounter).

Sorcim answered 9/5, 2014 at 10:31 Comment(0)
N
5

Try this:

(1) Write a small java program that locks a file and sleeps (or otherwise stops executing).

(2) cat /proc/locks

(3) You'll see lines like the following:

24: POSIX  ADVISORY  READ  1784 08:01:27384070 1073742826 1073742335
25: FLOCK  ADVISORY  WRITE 815  00:0f:9772     0          EOF

Identify your process ID from column 5. If column 2 is FLOCK then flock is being used. If it is POSIX then column 2 will be POSIX, indicating fcntl (or lockf which is build on top of fcntl) is being used.

If java has to choose one or the other then POSIX would be the sensible choice as it supports record locking.

Nordin answered 9/5, 2014 at 12:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.