This commit is contained in:
jfrijters 2005-04-11 08:05:42 +00:00
Родитель 8b98dc03ea
Коммит 22704a85cf
4 изменённых файлов: 155 добавлений и 9 удалений

Просмотреть файл

@ -55,7 +55,7 @@ import java.nio.channels.WritableByteChannel;
import cli.System.Console;
import cli.System.IO.*;
import ikvm.lang.CIL;
import gnu.classpath.RawData;
/**
* This file is not user visible !
@ -138,7 +138,7 @@ public final class FileChannelImpl extends FileChannel
if(false) throw new cli.System.UnauthorizedAccessException();
if(false) throw new cli.System.ArgumentException();
if(false) throw new cli.System.NotSupportedException();
return new cli.System.IO.FileStream(demanglePath(path), FileMode.wrap(fileMode), FileAccess.wrap(fileAccess), FileShare.wrap(FileShare.ReadWrite), 1, false);
return new FileStream(demanglePath(path), FileMode.wrap(fileMode), FileAccess.wrap(fileAccess), FileShare.wrap(FileShare.ReadWrite), 1, false);
}
catch(cli.System.Security.SecurityException x1)
{
@ -514,12 +514,22 @@ public final class FileChannelImpl extends FileChannel
return result;
}
public MappedByteBuffer mapImpl (char mode, long position, int size) throws IOException
private MappedByteBuffer mapImpl (char mode, long position, int size) throws IOException
{
// TODO
throw new IOException("not implemented");
if (! (stream instanceof FileStream))
throw new IllegalArgumentException("only file streams can be mapped");
RawData address = mapViewOfFile((FileStream)stream, mode != 'r', mode == 'c', position, size);
if (address == null)
throw new IOException("file mapping failed");
return createMappedByteBufferImpl(address, size, mode == 'r');
}
private static native RawData mapViewOfFile(FileStream stream, boolean writeable, boolean copy_on_write, long position, int size);
// implementation in map.xml to bypass Java access checking
private static native MappedByteBuffer createMappedByteBufferImpl(RawData address, int size, boolean readonly);
public MappedByteBuffer map (FileChannel.MapMode mode,
long position, long size)
throws IOException
@ -566,16 +576,16 @@ public final class FileChannelImpl extends FileChannel
throw new IOException(x.getMessage());
}
if (stream instanceof cli.System.IO.FileStream)
if (stream instanceof FileStream)
{
if(!flush(((cli.System.IO.FileStream)stream)))
if(!flush(((FileStream)stream)))
{
throw new IOException();
}
}
}
private static native boolean flush(cli.System.IO.FileStream fs);
private static native boolean flush(FileStream fs);
// like transferTo, but with a count of less than 2Gbytes
private int smallTransferTo (long position, int count,

Просмотреть файл

@ -929,6 +929,17 @@
</body>
</method>
</class>
<class name="gnu.java.nio.channels.FileChannelImpl">
<method name="createMappedByteBufferImpl" sig="(Lgnu.classpath.RawData;IZ)Ljava.nio.MappedByteBuffer;">
<body>
<ldarg_0 />
<ldarg_1 />
<ldarg_2 />
<newobj class="java.nio.MappedByteBufferImpl" name="&lt;init&gt;" sig="(Lgnu.classpath.RawData;IZ)V" />
<ret />
</body>
</method>
</class>
<class name="java.nio.channels.VMChannels">
<method name="newInputStream" sig="(Lgnu.java.nio.channels.FileChannelImpl;)Ljava.io.FileInputStream;">
<body>

Просмотреть файл

@ -1,5 +1,5 @@
/*
Copyright (C) 2004 Jeroen Frijters
Copyright (C) 2004, 2005 Jeroen Frijters
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -57,6 +57,7 @@
}
#else
#include <gmodule.h>
#include <sys/mman.h>
#include "jni.h"
JNIEXPORT void* JNICALL ikvm_LoadLibrary(char* psz)
@ -80,4 +81,19 @@
else
return NULL;
}
JNIEXPORT void* JNICALL ikvm_mmap(int fd, jboolean writeable, jboolean copy_on_write, jlong position, jint size)
{
return mmap(0, size, writeable ? PROT_WRITE | PROT_READ : PROT_READ, copy_on_write ? MAP_PRIVATE : MAP_SHARED, fd, position);
}
JNIEXPORT int JNICALL ikvm_munmap(void* address, jint size)
{
return munmap(address, size);
}
JNIEXPORT int JNICALL ikvm_msync(void* address, jint size)
{
return msync(address, size, MS_SYNC);
}
#endif

Просмотреть файл

@ -34,6 +34,7 @@ using IKVM.Runtime;
using IKVM.Internal;
using NetSystem = System;
using RawData = gnu.classpath.RawData;
namespace IKVM.NativeCode.java
{
@ -1256,6 +1257,7 @@ namespace IKVM.NativeCode.gnu.java.nio.channels
{
public class FileChannelImpl
{
internal static readonly bool runningOnWindows;
private static readonly MethodInfo mono_1_0_Flush;
private static readonly MethodInfo mono_1_1_Flush;
@ -1264,9 +1266,11 @@ namespace IKVM.NativeCode.gnu.java.nio.channels
try
{
FlushFileBuffers(new IntPtr(-1));
runningOnWindows = true;
}
catch(TypeLoadException)
{
runningOnWindows = false;
// If we end up here, we're not running on Windows, so we'll try two Mono specific methods.
// TODO convert this to Mono.Unix
Type t = Type.GetType("Mono.Posix.Syscall, Mono.Posix");
@ -1324,6 +1328,111 @@ namespace IKVM.NativeCode.gnu.java.nio.channels
[DllImport("kernel32")]
private extern static bool FlushFileBuffers(IntPtr handle);
public static RawData mapViewOfFile(FileStream fs, bool writeable, bool copy_on_write, long position, int size)
{
try
{
if(runningOnWindows)
{
const uint PAGE_READONLY = 2;
const uint PAGE_READWRITE = 4;
const uint PAGE_WRITECOPY = 8;
IntPtr hFileMapping = CreateFileMapping(fs.Handle, IntPtr.Zero,
copy_on_write ? PAGE_WRITECOPY : (writeable ? PAGE_READWRITE : PAGE_READONLY),
0, (uint)size, null);
if(hFileMapping == IntPtr.Zero)
{
return null;
}
const uint FILE_MAP_WRITE = 2;
const uint FILE_MAP_READ = 4;
const uint FILE_MAP_COPY = 1;
IntPtr p = MapViewOfFile(hFileMapping,
copy_on_write ? FILE_MAP_COPY : (writeable ? FILE_MAP_WRITE : FILE_MAP_READ),
(uint)(position >> 32), (uint)position, (uint)size);
CloseHandle(hFileMapping);
if(p == IntPtr.Zero)
{
return null;
}
return new RawData(p);
}
else
{
return new RawData(ikvm_mmap(fs.Handle, writeable, copy_on_write, position, size));
}
}
finally
{
GC.KeepAlive(fs);
}
}
[DllImport("ikvm-native")]
private extern static IntPtr ikvm_mmap(IntPtr handle, bool writeable, bool copy_on_write, long position, int size);
[DllImport("kernel32")]
private extern static bool CloseHandle(IntPtr handle);
[DllImport("kernel32")]
private extern static IntPtr CreateFileMapping(IntPtr hFile, IntPtr lpAttributes, uint flProtect, uint dwMaximumSizeHigh, uint dwMaximumSizeLow, string lpName);
[DllImport("kernel32")]
private extern static IntPtr MapViewOfFile(IntPtr hFileMapping, uint dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow, uint dwNumberOfBytesToMap);
}
}
namespace IKVM.NativeCode.java.nio
{
public class MappedByteBufferImpl
{
public static void unmapImpl(object thiz)
{
IntPtr address = JVM.Library.getDirectBufferAddress(thiz);
if(gnu.java.nio.channels.FileChannelImpl.runningOnWindows)
{
UnmapViewOfFile(address);
}
else
{
ikvm_munmap(address, JVM.Library.getDirectBufferCapacity(thiz));
}
}
[DllImport("ikvm-native")]
private extern static int ikvm_munmap(IntPtr address, int size);
[DllImport("ikvm-native")]
private extern static int ikvm_msync(IntPtr address, int size);
[DllImport("kernel32")]
private extern static bool UnmapViewOfFile(IntPtr lpBaseAddress);
[DllImport("kernel32")]
private extern static bool FlushViewOfFile(IntPtr lpBaseAddress, uint dwNumberOfBytesToFlush);
public static bool isLoadedImpl(object thiz)
{
return false;
}
public static void loadImpl(object thiz)
{
}
public static void forceImpl(object thiz)
{
IntPtr address = JVM.Library.getDirectBufferAddress(thiz);
if(gnu.java.nio.channels.FileChannelImpl.runningOnWindows)
{
FlushViewOfFile(address, 0);
}
else
{
ikvm_msync(address, JVM.Library.getDirectBufferCapacity(thiz));
}
}
}
}