Skip to content

On Linux, FileShare.None doesn't seem to be taken into account when retrying to open a locked file #59995

Closed
@nicolasl-rc

Description

@nicolasl-rc

Description

We have 2 processes. The first one opens a file with an exclusive lock (using FileShare.None), and keeps this lock for some time. Another process starts and tries to open the same file with an exclusive lock (also using FileShare.None). And it retries to open it until it gets the exclusive lock.

Here are two small programs. First, test1 is started, then, after the lock is acquired (but before it is released), test2 is started.

using System;
using System.IO;
using System.Threading;

namespace test1
{
    class Program
    {
        static void Main(string[] args)
        {
            var lockfilepath = Path.Combine(Path.GetTempPath(), "test-lock");
            Console.WriteLine($"{DateTime.Now} test1 {lockfilepath}");
            using(var exclusiveLock = new FileStream(lockfilepath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None, 1, FileOptions.DeleteOnClose)) {
                Console.WriteLine($"{DateTime.Now} {lockfilepath} locked");
                Thread.Sleep(10 * 1000);
                Console.WriteLine($"{DateTime.Now} releasing lock");
            }
            Console.WriteLine($"{DateTime.Now} lock released");
        }
    }
}
using System;
using System.IO;
using System.Threading;

namespace test2
{
    class Program
    {
        static void Main(string[] args)
        {
            var lockfilepath = Path.Combine(Path.GetTempPath(), "test-lock");
            Console.WriteLine($"{DateTime.Now} test2 - {lockfilepath}");
            while(true) {
                try {
                    var exclusiveLock = new FileStream(lockfilepath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None, 1, FileOptions.DeleteOnClose);
                    break;
                } catch(Exception _) {
                    Console.WriteLine($"{DateTime.Now} retrying");
                    Thread.Sleep(1000);
                }
            }
            Console.WriteLine($"{DateTime.Now} lock acquired");
        }
    }
}

What we see:
The first attempt by test2 to open the file fails as expected. However, the second attempt succeeds, even though test1 still has the lock.

What we expect:
test2 should loop until test1 releases the lock.

Configuration

.NET version: 6.0.100-rc.1.21463.6
OS: Linux (distro: rocky linux 8)
Architecture: x64

Regression?

This works as expected on Windows (.NET Framework 4.8, .NET Core 3.1, .NET 6 RC1) and Linux with .NET Core 3.1.

It seems to be linked to the use of FileOptions.DeleteOnClose. Using FileOptions.None gives the expected behavior.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions