コード例 #1
0
        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);
        }
コード例 #2
0
        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);
            }
                       ));
        }