public static bool DuplicateHandle( global::System.IntPtr hSourceProcessHandle, global::System.IntPtr hSourceHandle, global::System.IntPtr hTargetProcessHandle, out global::System.IntPtr lpTargetHandle, uint dwDesiredAccess, bool bInheritHandle, uint dwOptions ) { global::System.IntPtr dupHandle = global::System.IntPtr.Zero; bool retVal = Helper.SimpleWrap <bool>( delegate(ClrSyncManager manager) { bool flag = OrigNativeMethods.DuplicateHandle(hSourceProcessHandle, hSourceHandle, hTargetProcessHandle, out dupHandle, dwDesiredAccess, bInheritHandle, dwOptions); if (flag) { if (hSourceHandle == OrigNativeMethods.GetCurrentThread()) { // associate the dup handle with the current running tid // Also, we want a Native IJoinable for this thread as there can be race // when the CLR thinks a thread is dead, but Win32 does not // So, a subsequent WaitForMultipleObjects() can fail global::System.IntPtr childHandleCp; bool dupret = OrigNativeMethods.DuplicateHandle( OrigNativeMethods.GetCurrentProcess(), dupHandle, OrigNativeMethods.GetCurrentProcess(), out childHandleCp, 0, false, OrigNativeMethods.DUPLICATE_SAME_ACCESS); global::System.Diagnostics.Debug.Assert(dupret); manager.AddIJoinable(manager.CurrentTid, new NativeThreadJoinable(childHandleCp, global::System.Threading.Thread.CurrentThread.Name)); manager.AddNativeHandleForSyncVar(dupHandle, manager.CurrentTid); } else { manager.DuplicateNativeHandle(hSourceHandle, dupHandle); } } return(flag); }, delegate() { return(OrigNativeMethods.DuplicateHandle(hSourceProcessHandle, hSourceHandle, hTargetProcessHandle, out dupHandle, dwDesiredAccess, bInheritHandle, dwOptions)); }); lpTargetHandle = dupHandle; return(retVal); }
public static global::System.IntPtr CreateThread( global::System.IntPtr lpThreadAttributes, global::System.IntPtr dwStackSize, global::System.IntPtr lpStartAddress, global::System.IntPtr lpParameter, int dwCreationFlags, global::System.IntPtr lpThreadId ) { return(Helper.SimpleWrap <global::System.IntPtr>( delegate(ClrSyncManager manager) { Original.Semaphore semaphore = new Original.Semaphore(0, 1); int childThread = manager.TaskFork(); Win32ThreadStartDelegate wrapper = delegate(global::System.IntPtr argPtr) { try { manager.ThreadBegin(semaphore); int returnValue = 0; Exception exception = null; Microsoft.ManagedChess.MChessChess.LeaveChess(); try { returnValue = CallThreadFunction(lpStartAddress, lpParameter); } catch (Exception e) // catch recoverable exception in monitored code { exception = e; } Microsoft.ManagedChess.MChessChess.EnterChess(); if (manager.BreakDeadlockMode) { Microsoft.ManagedChess.MChessChess.WakeNextDeadlockedThread(false, true); } else if (exception == null) { manager.ThreadEnd(childThread); } else { manager.Shutdown(exception); } return returnValue; } catch (Exception e) // catch fatal exception in our code { manager.Shutdown(e); return -1; } }; //make sure wrapper does not get GCed manager.PinObject(wrapper); global::System.IntPtr wrapperPointer = Marshal.GetFunctionPointerForDelegate(wrapper); global::System.IntPtr returnVal = OrigNativeMethods.CreateThread(lpThreadAttributes, dwStackSize, wrapperPointer, global::System.IntPtr.Zero, dwCreationFlags, lpThreadId); if ((dwCreationFlags & OrigNativeMethods.CREATE_SUSPENDED) == 0) { manager.TaskResume(childThread); } manager.RegisterTaskSemaphore(childThread, semaphore, true); global::System.IntPtr childHandleCp; bool dupret = OrigNativeMethods.DuplicateHandle( OrigNativeMethods.GetCurrentProcess(), returnVal, OrigNativeMethods.GetCurrentProcess(), out childHandleCp, 0, false, OrigNativeMethods.DUPLICATE_SAME_ACCESS); global::System.Diagnostics.Debug.Assert(dupret); manager.AddIJoinable(childThread, new NativeThreadJoinable(childHandleCp)); manager.AddNativeHandleForSyncVar(returnVal, childThread); return returnVal; }, delegate() { // default to direct call return OrigNativeMethods.CreateThread(lpThreadAttributes, dwStackSize, lpStartAddress, lpParameter, dwCreationFlags, lpThreadId); } )); }