Ejemplo n.º 1
0
 public static void Yield()
 {
     Helper.SimpleWrap <bool>(
         delegate(ClrSyncManager manager)
     {
         manager.TaskYield(); return(false);
     },
         delegate() { OrigNativeMethods.SwitchToThread(); return(false); });
 }
Ejemplo n.º 2
0
 public static int SwitchToThread()
 {
     return(Helper.SimpleWrap <int>(
                delegate(ClrSyncManager manager)
     {
         manager.TaskYield();
         return OrigNativeMethods.SwitchToThread();
     },
                delegate() { return OrigNativeMethods.SwitchToThread(); }));
 }
Ejemplo n.º 3
0
 public static bool SetEvent(
     global::System.IntPtr hEvent
     )
 {
     return(Helper.WrapRelease(
                hEvent,
                MSyncVarOp.RWEVENT,
                delegate(object o) { return OrigNativeMethods.SetEvent((global::System.IntPtr)o); },
                "Win32Event.Set"
                ));
 }
Ejemplo n.º 4
0
        public unsafe static int WaitForMultipleObjects(
            int nCount,
            global::System.IntPtr *lpHandles,
            bool bWaitAll,
            int dwMilliseconds
            )
        {
            return(Helper.SimpleWrap <int>(
                       delegate(ClrSyncManager manager)
            {
                SyncVar[] v = new SyncVar[nCount];
                for (int i = 0; i < nCount; i++)
                {
                    v[i] = manager.GetSyncVarFromNativeHandle(lpHandles[i]);
                }

                int returnVal;
                while (true)
                {
                    manager.SetMethodInfo(bWaitAll ? "Win32WaitForMultipleObjects::WAIT_ALL" : "Win32WaitForMultipleObjects::WAIT_ANY");
                    manager.AggregateSyncVarAccess(v, bWaitAll ? MSyncVarOp.WAIT_ALL : MSyncVarOp.WAIT_ANY);
                    try
                    {
                        returnVal = OrigNativeMethods.WaitForMultipleObjects(nCount, lpHandles, bWaitAll, 0);
                    }
                    catch (Exception e)
                    {
                        manager.CommitSyncVarAccess();
                        throw e;
                    }
                    if (OrigNativeMethods.WAIT_OBJECT_0 <= returnVal && returnVal <= OrigNativeMethods.WAIT_OBJECT_0 + nCount - 1)
                    {
                        // success
                        manager.CommitSyncVarAccess();
                        return returnVal;
                    }
                    global::System.Diagnostics.Debug.Assert(returnVal == OrigNativeMethods.WAIT_TIMEOUT);
                    if (dwMilliseconds != OrigNativeMethods.INFINITE)
                    {
                        // timeout
                        manager.MarkTimeout();
                        manager.CommitSyncVarAccess();
                        manager.TaskYield();
                        return returnVal;
                    }
                    manager.LocalBacktrack();
                }
            },
                       delegate()
            {
                return OrigNativeMethods.WaitForMultipleObjects(nCount, lpHandles, bWaitAll, dwMilliseconds);
            }));
        }
Ejemplo n.º 5
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);
        }
Ejemplo n.º 6
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);
            }
                       ));
        }
Ejemplo n.º 7
0
 public void Join()
 {
     OrigNativeMethods.WaitForSingleObject(handle, OrigNativeMethods.INFINITE);
 }