Skip to content

Commit

Permalink
Merge develop.
Browse files Browse the repository at this point in the history
  • Loading branch information
wasabii committed Aug 17, 2023
2 parents 1628512 + 5efacb1 commit ef520bc
Show file tree
Hide file tree
Showing 33 changed files with 327 additions and 41 deletions.
2 changes: 1 addition & 1 deletion openjdk.props
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project>
<Project>
<ItemDefinitionGroup>
<OpenJdkSource>
<SourcePath>%(Identity)</SourcePath>
Expand Down
2 changes: 1 addition & 1 deletion src/IKVM.Runtime/IKVM.Runtime.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NETCore.Platforms" Version="7.0.3" GeneratePathProperty="true" />
<PackageReference Include="Microsoft.NETCore.Platforms" Version="8.0.0-preview.7.23375.6" GeneratePathProperty="true" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,68 @@ static unsafe ValueTask LockFileExAsync(SafeFileHandle hFile, int dwFlags, int d
[DllImport("kernel32", SetLastError = true)]
static extern unsafe int UnlockFileEx(SafeFileHandle hFile, int dwReserved, int nNumberOfBytesToUnlockLow, int nNumberOfBytesToUnlockHigh, NativeOverlapped* lpOverlapped);

/// <summary>
/// Record locking flags for OS X.
/// </summary>
enum OSX_LockType : short
{

F_RDLCK = 1,
F_UNLCK = 2,
F_WRLCK = 3,

}

/// <summary>
/// Flock structure on OSX. Fields are in a different order than Mono.Posix.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
struct OSX_Flock
{

public long l_start;
public long l_len;
public int l_pid;
public OSX_LockType l_type;
public SeekFlags l_whence;

}

/// <summary>
/// 'fcntl' command values for OS X.
/// </summary>
enum OSX_FcntlCommand
{

F_GETLK = 7,
F_SETLK = 8,
F_SETLKW = 9,

}

/// <summary>
/// 'errno' values for OS X.
/// </summary>
enum OSX_Errno
{

EAGAIN = 35,
EACCES = 13,
EINTR = 4,
EDEADLK = 11,

}

/// <summary>
/// Invokes the 'fcntl' function on OS X.
/// </summary>
/// <param name="fd"></param>
/// <param name="cmd"></param>
/// <param name="lock"></param>
/// <returns></returns>
[DllImport("c", SetLastError = true, EntryPoint = "fcntl")]
static extern int OSX_fcntl(int fd, OSX_FcntlCommand cmd, ref OSX_Flock @lock);

/// <summary>
/// Implements the Lock logic as an asynchronous task.
/// </summary>
Expand Down Expand Up @@ -460,7 +522,7 @@ async Task<FileLock> ImplAsync()
throw new global::java.io.IOException(e);
}
}
else if (RuntimeUtil.IsLinux || RuntimeUtil.IsOSX)
else if (RuntimeUtil.IsLinux)
{
while (true)
{
Expand All @@ -480,14 +542,20 @@ async Task<FileLock> ImplAsync()
fl.l_type = shared ? LockType.F_RDLCK : LockType.F_WRLCK;

// fails immediately with EAGAIN or EACCES if cannot obtain
if (Syscall.fcntl((int)fs.SafeFileHandle.DangerousGetHandle(), FcntlCommand.F_SETLK, ref fl) == 0)
return fli;

var errno = Syscall.GetLastError();
if (errno == Errno.EAGAIN || errno == Errno.EACCES)
continue;
var r = Syscall.fcntl((int)fs.SafeFileHandle.DangerousGetHandle(), FcntlCommand.F_SETLK, ref fl);
if (r == -1)
{
var errno = Stdlib.GetLastError();
if (errno == Errno.EAGAIN || errno == Errno.EACCES)
{
await Task.Delay(TimeSpan.FromMilliseconds(100));
continue;
}

UnixMarshal.ThrowExceptionForError(errno);
}

UnixMarshal.ThrowExceptionForError(errno);
return fli;
}
finally
{
Expand All @@ -506,8 +574,60 @@ async Task<FileLock> ImplAsync()
{
throw new global::java.io.IOException(e);
}
}
}
else if (RuntimeUtil.IsOSX)
{
while (true)
{
try
{
if (cancellationToken.IsCancellationRequested)
return null;

try
{
self.begin();

await Task.Delay(TimeSpan.FromMilliseconds(100));
var fl = new OSX_Flock();
fl.l_whence = SeekFlags.SEEK_SET;
fl.l_len = size == long.MaxValue ? 0 : size;
fl.l_start = position;
fl.l_type = shared ? OSX_LockType.F_RDLCK : OSX_LockType.F_WRLCK;

// fails immediately with EAGAIN or EACCES if cannot obtain
var r = OSX_fcntl((int)fs.SafeFileHandle.DangerousGetHandle(), OSX_FcntlCommand.F_SETLK, ref fl);
if (r == -1)
{
var errno = (OSX_Errno)(int)Stdlib.GetLastError();
if (errno == OSX_Errno.EAGAIN || errno == OSX_Errno.EACCES)
{
await Task.Delay(TimeSpan.FromMilliseconds(100));
continue;
}

UnixMarshal.ThrowExceptionForError((Errno)(int)errno);
}

return fli;
}
finally
{
self.end();
}
}
catch (ObjectDisposedException)
{
throw new global::java.nio.channels.AsynchronousCloseException();
}
catch (System.Exception) when (IsOpen(self) == false)
{
throw new global::java.nio.channels.AsynchronousCloseException();
}
catch (System.Exception e)
{
throw new global::java.io.IOException(e);
}
}
}
else
Expand Down Expand Up @@ -615,7 +735,7 @@ static unsafe FileLock TryLock(global::sun.nio.ch.DotNetAsynchronousFileChannelI

return fli;
}
else if (RuntimeUtil.IsLinux || RuntimeUtil.IsOSX)
else if (RuntimeUtil.IsLinux)
{
var fl = new Flock();
fl.l_whence = SeekFlags.SEEK_SET;
Expand All @@ -636,6 +756,27 @@ static unsafe FileLock TryLock(global::sun.nio.ch.DotNetAsynchronousFileChannelI

UnixMarshal.ThrowExceptionForError(errno);
}
else if (RuntimeUtil.IsOSX)
{
var fl = new OSX_Flock();
fl.l_whence = SeekFlags.SEEK_SET;
fl.l_len = size == long.MaxValue ? 0 : size;
fl.l_start = position;
fl.l_type = shared ? OSX_LockType.F_RDLCK : OSX_LockType.F_WRLCK;

// fails immediately with EAGAIN or EACCES if cannot obtain
if (OSX_fcntl((int)fs.SafeFileHandle.DangerousGetHandle(), OSX_FcntlCommand.F_SETLK, ref fl) == 0)
return fli;

var errno = (OSX_Errno)Stdlib.GetLastError();
if (errno == OSX_Errno.EAGAIN || errno == OSX_Errno.EACCES)
{
self.removeFromFileLockTable(fli);
return null;
}

UnixMarshal.ThrowExceptionForError((Errno)(int)errno);
}
else
{
fs.Lock(position, size);
Expand Down Expand Up @@ -715,7 +856,7 @@ static unsafe void Release(global::sun.nio.ch.DotNetAsynchronousFileChannelImpl
return;
}
}
else if (RuntimeUtil.IsLinux || RuntimeUtil.IsOSX)
else if (RuntimeUtil.IsLinux)
{
var fl = new Flock();
fl.l_whence = SeekFlags.SEEK_SET;
Expand All @@ -727,6 +868,18 @@ static unsafe void Release(global::sun.nio.ch.DotNetAsynchronousFileChannelImpl
if (r == -1)
UnixMarshal.ThrowExceptionForLastErrorIf(r);
}
else if (RuntimeUtil.IsOSX)
{
var fl = new OSX_Flock();
fl.l_whence = SeekFlags.SEEK_SET;
fl.l_len = size == long.MaxValue ? 0 : size;
fl.l_start = pos;
fl.l_type = OSX_LockType.F_UNLCK;

var r = OSX_fcntl((int)fs.SafeFileHandle.DangerousGetHandle(), OSX_FcntlCommand.F_SETLK, ref fl);
if (r == -1)
UnixMarshal.ThrowExceptionForLastErrorIf(r);
}
else
{
fs.Unlock(pos, size);
Expand Down
101 changes: 99 additions & 2 deletions src/IKVM.Runtime/Java/Externs/sun/nio/ch/FileDispatcherImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -717,6 +717,68 @@ public static long size0(object fd)
[DllImport("kernel32", SetLastError = true)]
static extern unsafe int UnlockFileEx(SafeFileHandle hFile, int dwReserved, int nNumberOfBytesToUnlockLow, int nNumberOfBytesToUnlockHigh, NativeOverlapped* lpOverlapped);

/// <summary>
/// Record locking flags for OS X.
/// </summary>
enum OSX_LockType : short
{

F_RDLCK = 1,
F_UNLCK = 2,
F_WRLCK = 3,

}

/// <summary>
/// Flock structure on OSX. Fields are in a different order than Mono.Posix.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
struct OSX_Flock
{

public long l_start;
public long l_len;
public int l_pid;
public OSX_LockType l_type;
public SeekFlags l_whence;

}

/// <summary>
/// 'fcntl' command values for OS X.
/// </summary>
enum OSX_FcntlCommand
{

F_GETLK = 7,
F_SETLK = 8,
F_SETLKW = 9,

}

/// <summary>
/// 'errno' values for OS X.
/// </summary>
enum OSX_Errno
{

EAGAIN = 35,
EACCES = 13,
EINTR = 4,
EDEADLK = 11,

}

/// <summary>
/// Invokes the 'fcntl' function on OS X.
/// </summary>
/// <param name="fd"></param>
/// <param name="cmd"></param>
/// <param name="lock"></param>
/// <returns></returns>
[DllImport("c", SetLastError = true, EntryPoint = "fcntl")]
static extern int OSX_fcntl(int fd, OSX_FcntlCommand cmd, ref OSX_Flock @lock);

/// <summary>
/// Implements the native method 'lock'.
/// </summary>
Expand Down Expand Up @@ -780,7 +842,7 @@ public static unsafe int lock0(object fd, bool blocking, long pos, long size, bo
Overlapped.Free(optr);
}
}
else if (RuntimeUtil.IsLinux || RuntimeUtil.IsOSX)
else if (RuntimeUtil.IsLinux)
{
var fl = new Flock();
fl.l_whence = SeekFlags.SEEK_SET;
Expand All @@ -803,6 +865,29 @@ public static unsafe int lock0(object fd, bool blocking, long pos, long size, bo

return FileDispatcher.LOCKED;
}
else if (RuntimeUtil.IsOSX)
{
var fl = new OSX_Flock();
fl.l_whence = SeekFlags.SEEK_SET;
fl.l_len = size == long.MaxValue ? 0 : size;
fl.l_start = pos;
fl.l_type = shared ? OSX_LockType.F_RDLCK : OSX_LockType.F_WRLCK;
var cmd = blocking ? OSX_FcntlCommand.F_SETLKW : OSX_FcntlCommand.F_SETLK;

var r = OSX_fcntl((int)fs.SafeFileHandle.DangerousGetHandle(), cmd, ref fl);
if (r == -1)
{
var errno = (OSX_Errno)Stdlib.GetLastError();
if ((cmd == OSX_FcntlCommand.F_SETLK) && (errno == OSX_Errno.EAGAIN || errno == OSX_Errno.EACCES))
return FileDispatcher.NO_LOCK;
if (errno == OSX_Errno.EINTR)
return FileDispatcher.INTERRUPTED;

UnixMarshal.ThrowExceptionForError((Errno)(int)errno);
}

return FileDispatcher.LOCKED;
}
else
{
// fallback to .NET version for non-Windows
Expand Down Expand Up @@ -876,7 +961,7 @@ public static unsafe void release0(object fd, long pos, long size)
Overlapped.Free(optr);
}
}
else if (RuntimeUtil.IsLinux || RuntimeUtil.IsOSX)
else if (RuntimeUtil.IsLinux)
{
var fl = new Flock();
fl.l_whence = SeekFlags.SEEK_SET;
Expand All @@ -888,6 +973,18 @@ public static unsafe void release0(object fd, long pos, long size)
if (r == -1)
UnixMarshal.ThrowExceptionForLastErrorIf(r);
}
else if (RuntimeUtil.IsOSX)
{
var fl = new OSX_Flock();
fl.l_whence = SeekFlags.SEEK_SET;
fl.l_len = size == long.MaxValue ? 0 : size;
fl.l_start = pos;
fl.l_type = OSX_LockType.F_UNLCK;

var r = OSX_fcntl((int)fs.SafeFileHandle.DangerousGetHandle(), OSX_FcntlCommand.F_SETLK, ref fl);
if (r == -1)
UnixMarshal.ThrowExceptionForLastErrorIf(r);
}
else
{
fs.Unlock(pos, size);
Expand Down
Loading

0 comments on commit ef520bc

Please sign in to comment.