diff --git a/src/dotnet/FileSystemHost.cs b/src/dotnet/FileSystemHost.cs index 60c15762..dc8ff961 100644 --- a/src/dotnet/FileSystemHost.cs +++ b/src/dotnet/FileSystemHost.cs @@ -56,7 +56,7 @@ namespace Fsp { ExceptionHandler(_FileSystem, ex); } - Api.SetUserContext(_FileSystemPtr, null); + Api.DisposeUserContext(_FileSystemPtr); Api.FspFileSystemDelete(_FileSystemPtr); _FileSystemPtr = IntPtr.Zero; } @@ -210,7 +210,7 @@ namespace Fsp } if (0 > Result) { - Api.SetUserContext(_FileSystemPtr, null); + Api.DisposeUserContext(_FileSystemPtr); Api.FspFileSystemDelete(_FileSystemPtr); _FileSystemPtr = IntPtr.Zero; } @@ -457,7 +457,7 @@ namespace Fsp FileSystem.Close( FileNode, FileDesc); - Api.SetFullContext(ref FullContext, null, null); + Api.DisposeFullContext(ref FullContext); } catch (Exception ex) { @@ -917,8 +917,8 @@ namespace Fsp private static FileSystemInterface _FileSystemInterface; private static IntPtr _FileSystemInterfacePtr; private VolumeParams _VolumeParams; - private IntPtr _FileSystemPtr; private FileSystemBase _FileSystem; + private IntPtr _FileSystemPtr; } } diff --git a/src/dotnet/Interop.cs b/src/dotnet/Interop.cs index d90737e6..be1874ac 100644 --- a/src/dotnet/Interop.cs +++ b/src/dotnet/Interop.cs @@ -721,61 +721,61 @@ namespace Fsp.Interop IntPtr NativePtr, Object Obj) { - if (null != Obj) + Debug.Assert(IntPtr.Zero == *(IntPtr *)((Byte *)NativePtr + sizeof(IntPtr))); + GCHandle Handle = GCHandle.Alloc(Obj, GCHandleType.Weak); + *(IntPtr *)((Byte *)NativePtr + sizeof(IntPtr)) = (IntPtr)Handle; + } + internal unsafe static void DisposeUserContext( + IntPtr NativePtr) + { + IntPtr UserContext = *(IntPtr *)((Byte *)NativePtr + sizeof(IntPtr)); + Debug.Assert(IntPtr.Zero != UserContext); + if (IntPtr.Zero != UserContext) { - Debug.Assert(IntPtr.Zero == *(IntPtr *)((Byte *)NativePtr + sizeof(IntPtr))); - GCHandle Handle = GCHandle.Alloc(Obj, GCHandleType.Weak); - *(IntPtr *)((Byte *)NativePtr + sizeof(IntPtr)) = (IntPtr)Handle; - } - else - { - IntPtr UserContext = *(IntPtr *)((Byte *)NativePtr + sizeof(IntPtr)); - if (IntPtr.Zero != UserContext) - { - GCHandle.FromIntPtr(UserContext).Free(); - *(IntPtr *)((Byte *)NativePtr + sizeof(IntPtr)) = IntPtr.Zero; - } + GCHandle.FromIntPtr(UserContext).Free(); + *(IntPtr *)((Byte *)NativePtr + sizeof(IntPtr)) = IntPtr.Zero; } } + private class FullContextHolder + { + public Object FileNode; + public Object FileDesc; + } internal static void GetFullContext(ref FullContext FullContext, out Object FileNode, out Object FileDesc) { - FileNode = 0 != FullContext.UserContext ? - GCHandle.FromIntPtr((IntPtr)FullContext.UserContext).Target : null; - FileDesc = 0 != FullContext.UserContext2 ? - GCHandle.FromIntPtr((IntPtr)FullContext.UserContext2).Target : null; + FullContextHolder Holder = 0 != FullContext.UserContext2 ? + (FullContextHolder)GCHandle.FromIntPtr((IntPtr)FullContext.UserContext2).Target : + null; + if (null != Holder) + { + FileNode = Holder.FileNode; + FileDesc = Holder.FileDesc; + } + else + { + FileNode = null; + FileDesc = null; + } } internal static void SetFullContext(ref FullContext FullContext, Object FileNode, Object FileDesc) { - if (null != FileNode) + Debug.Assert(0 == FullContext.UserContext && 0 == FullContext.UserContext2); + FullContextHolder Holder = new FullContextHolder(); + Holder.FileNode = FileNode; + Holder.FileDesc = FileDesc; + GCHandle Handle = GCHandle.Alloc(Holder, GCHandleType.Normal); + FullContext.UserContext2 = (UInt64)(IntPtr)Handle; + } + internal static void DisposeFullContext(ref FullContext FullContext) + { + Debug.Assert(0 == FullContext.UserContext && 0 != FullContext.UserContext2); + if (0 != FullContext.UserContext2) { - Debug.Assert(0 == FullContext.UserContext); - GCHandle Handle = GCHandle.Alloc(FileNode, GCHandleType.Normal); - FullContext.UserContext = (UInt64)(IntPtr)Handle; - } - else - { - if (0 != FullContext.UserContext) - { - GCHandle.FromIntPtr((IntPtr)FullContext.UserContext).Free(); - FullContext.UserContext = 0; - } - } - if (null != FileDesc) - { - Debug.Assert(0 == FullContext.UserContext2); - GCHandle Handle = GCHandle.Alloc(FileDesc, GCHandleType.Normal); - FullContext.UserContext2 = (UInt64)(IntPtr)Handle; - } - else - { - if (0 != FullContext.UserContext2) - { - GCHandle.FromIntPtr((IntPtr)FullContext.UserContext2).Free(); - FullContext.UserContext2 = 0; - } + GCHandle.FromIntPtr((IntPtr)FullContext.UserContext2).Free(); + FullContext.UserContext2 = 0; } } diff --git a/src/dotnet/Service.cs b/src/dotnet/Service.cs index af8b88df..5b8aa1b4 100644 --- a/src/dotnet/Service.cs +++ b/src/dotnet/Service.cs @@ -33,23 +33,23 @@ namespace Fsp /* ctor/dtor */ public Service(String ServiceName) { - Api.FspServiceCreate(ServiceName, _OnStart, _OnStop, null, out _Service); - if (IntPtr.Zero != _Service) - Api.SetUserContext(_Service, this); + Api.FspServiceCreate(ServiceName, _OnStart, _OnStop, null, out _ServicePtr); + if (IntPtr.Zero != _ServicePtr) + Api.SetUserContext(_ServicePtr, this); } ~Service() { - if (IntPtr.Zero != _Service) + if (IntPtr.Zero != _ServicePtr) { - Api.SetUserContext(_Service, null); - Api.FspServiceDelete(_Service); + Api.DisposeUserContext(_ServicePtr); + Api.FspServiceDelete(_ServicePtr); } } /* control */ public int Run() { - if (IntPtr.Zero == _Service) + if (IntPtr.Zero == _ServicePtr) { const Int32 STATUS_INSUFFICIENT_RESOURCES = unchecked((Int32)0xc000009a); Log(EVENTLOG_ERROR_TYPE, @@ -57,9 +57,9 @@ namespace Fsp GetType().FullName, STATUS_INSUFFICIENT_RESOURCES)); return (int)Api.FspWin32FromNtStatus(STATUS_INSUFFICIENT_RESOURCES); } - Api.FspServiceAllowConsoleMode(_Service); - Int32 Result = Api.FspServiceLoop(_Service); - int ExitCode = (int)Api.FspServiceGetExitCode(_Service); + Api.FspServiceAllowConsoleMode(_ServicePtr); + Int32 Result = Api.FspServiceLoop(_ServicePtr); + int ExitCode = (int)Api.FspServiceGetExitCode(_ServicePtr); if (0 > Result) { Log(EVENTLOG_ERROR_TYPE, @@ -71,34 +71,34 @@ namespace Fsp } public void Stop() { - if (IntPtr.Zero == _Service) + if (IntPtr.Zero == _ServicePtr) throw new InvalidOperationException(); - Api.FspServiceStop(_Service); + Api.FspServiceStop(_ServicePtr); } public void RequestTime(UInt32 Time) { - if (IntPtr.Zero == _Service) + if (IntPtr.Zero == _ServicePtr) throw new InvalidOperationException(); - Api.FspServiceRequestTime(_Service, Time); + Api.FspServiceRequestTime(_ServicePtr, Time); } public int ExitCode { get { - if (IntPtr.Zero == _Service) + if (IntPtr.Zero == _ServicePtr) throw new InvalidOperationException(); - return (int)Api.FspServiceGetExitCode(_Service); + return (int)Api.FspServiceGetExitCode(_ServicePtr); } set { - if (IntPtr.Zero == _Service) + if (IntPtr.Zero == _ServicePtr) throw new InvalidOperationException(); - Api.FspServiceSetExitCode(_Service, (UInt32)value); + Api.FspServiceSetExitCode(_ServicePtr, (UInt32)value); } } public IntPtr ServiceHandle { - get { return _Service; } + get { return _ServicePtr; } } public static void Log(UInt32 Type, String Message) { @@ -152,7 +152,7 @@ namespace Fsp private static Api.Proto.ServiceStart _OnStart = OnStart; private static Api.Proto.ServiceStop _OnStop = OnStop; - private IntPtr _Service; + private IntPtr _ServicePtr; } }