dotnet: fix problems with FullContext and GCHandle

This commit is contained in:
Bill Zissimopoulos 2017-05-07 15:13:22 -07:00
parent 8c5d9bda20
commit bf64bcf9ba
3 changed files with 67 additions and 67 deletions

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}