コード例 #1
0
        internal RegisteredWaitHandle(SafeWaitHandle waitHandle, _ThreadPoolWaitOrTimerCallback callbackHelper,
                                      uint millisecondsTimeout, bool repeating)
        {
            _lock = new Lock();

            // Protect the handle from closing while we are waiting on it (VSWhidbey 285642)
            waitHandle.DangerousAddRef();
            _waitHandle = waitHandle;

            _callbackHelper      = callbackHelper;
            _millisecondsTimeout = millisecondsTimeout;
            _repeating           = repeating;

            // Allocate _gcHandle and _tpWait as the last step and make sure they are never leaked
            _gcHandle = GCHandle.Alloc(this);

            _tpWait = Interop.mincore.CreateThreadpoolWait(
                AddrofIntrinsics.AddrOf <Interop.mincore.WaitCallback>(RegisteredWaitCallback), (IntPtr)_gcHandle, IntPtr.Zero);

            if (_tpWait == IntPtr.Zero)
            {
                _gcHandle.Free();
                throw new OutOfMemoryException();
            }
        }
コード例 #2
0
        public static ThreadPoolBoundHandle BindHandle(SafeHandle handle)
        {
            if (handle == null)
            {
                throw new ArgumentNullException(nameof(handle));
            }

            if (handle.IsClosed || handle.IsInvalid)
            {
                throw new ArgumentException(SR.Argument_InvalidHandle, nameof(handle));
            }

            IntPtr callback = AddrofIntrinsics.AddrOf <Interop.NativeIoCompletionCallback>(OnNativeIOCompleted);
            SafeThreadPoolIOHandle threadPoolHandle = Interop.mincore.CreateThreadpoolIo(handle, callback, IntPtr.Zero, IntPtr.Zero);

            if (threadPoolHandle.IsInvalid)
            {
                int errorCode = Marshal.GetLastWin32Error();
                if (errorCode == Interop.Errors.ERROR_INVALID_HANDLE)         // Bad handle
                {
                    throw new ArgumentException(SR.Argument_InvalidHandle, nameof(handle));
                }

                if (errorCode == Interop.Errors.ERROR_INVALID_PARAMETER)     // Handle already bound or sync handle
                {
                    throw new ArgumentException(SR.Argument_AlreadyBoundOrSyncHandle, nameof(handle));
                }

                throw Win32Marshal.GetExceptionForWin32Error(errorCode);
            }

            return(new ThreadPoolBoundHandle(handle, threadPoolHandle));
        }
コード例 #3
0
        // Enumerate all system cultures and then try to find out which culture has
        // region name match the requested region name
        private static CultureData GetCultureDataFromRegionName(String regionName)
        {
            Debug.Assert(regionName != null);

            const uint LOCALE_SUPPLEMENTAL = 0x00000002;
            const uint LOCALE_SPECIFICDATA = 0x00000020;

            EnumLocaleData context = new EnumLocaleData();

            context.cultureName = null;
            context.regionName  = regionName;

            GCHandle contextHandle = GCHandle.Alloc(context);

            try
            {
                IntPtr callback = AddrofIntrinsics.AddrOf <Func <IntPtr, uint, IntPtr, Interop.BOOL> >(EnumSystemLocalesProc);
                Interop.mincore.EnumSystemLocalesEx(callback, LOCALE_SPECIFICDATA | LOCALE_SUPPLEMENTAL, (IntPtr)contextHandle, IntPtr.Zero);
            }
            finally
            {
                contextHandle.Free();
            }

            if (context.cultureName != null)
            {
                // we got a matched culture
                return(GetCultureData(context.cultureName, true));
            }

            return(null);
        }
コード例 #4
0
        private static CultureInfo[] EnumCultures(CultureTypes types)
        {
            Debug.Assert(!GlobalizationMode.Invariant);

            uint flags = 0;

#pragma warning disable 618
            if ((types & (CultureTypes.FrameworkCultures | CultureTypes.InstalledWin32Cultures | CultureTypes.ReplacementCultures)) != 0)
            {
                flags |= Interop.Kernel32.LOCALE_NEUTRALDATA | Interop.Kernel32.LOCALE_SPECIFICDATA;
            }
#pragma warning restore 618

            if ((types & CultureTypes.NeutralCultures) != 0)
            {
                flags |= Interop.Kernel32.LOCALE_NEUTRALDATA;
            }

            if ((types & CultureTypes.SpecificCultures) != 0)
            {
                flags |= Interop.Kernel32.LOCALE_SPECIFICDATA;
            }

            if ((types & CultureTypes.UserCustomCulture) != 0)
            {
                flags |= Interop.Kernel32.LOCALE_SUPPLEMENTAL;
            }

            if ((types & CultureTypes.ReplacementCultures) != 0)
            {
                flags |= Interop.Kernel32.LOCALE_SUPPLEMENTAL;
            }

            EnumData context = new EnumData();
            context.strings = new StringList();
            GCHandle contextHandle = GCHandle.Alloc(context);
            try
            {
#if CORECLR
                Interop.Kernel32.EnumSystemLocalesEx(EnumAllSystemLocalesProc, flags, (IntPtr)contextHandle, IntPtr.Zero);
#else
                IntPtr callback = AddrofIntrinsics.AddrOf <Func <IntPtr, uint, IntPtr, Interop.BOOL> >(EnumAllSystemLocalesProc);
                Interop.Kernel32.EnumSystemLocalesEx(callback, flags, (IntPtr)contextHandle, IntPtr.Zero);
#endif
            }
            finally
            {
                contextHandle.Free();
            }

            CultureInfo [] cultures = new CultureInfo[context.strings.Count];
            for (int i = 0; i < cultures.Length; i++)
            {
                cultures[i] = new CultureInfo(context.strings[i]);
            }

            return(cultures);
        }
コード例 #5
0
        private static unsafe String[] nativeEnumTimeFormats(String localeName, uint dwFlags, bool useUserOverride)
        {
            const uint LOCALE_SSHORTTIME  = 0x00000079;
            const uint LOCALE_STIMEFORMAT = 0x00001003;

            EnumData data = new EnumData();

            data.strings = new StringList();
            GCHandle dataHandle = GCHandle.Alloc(data);

            try
            {
#if CORECLR
                Interop.Kernel32.EnumTimeFormatsEx(EnumTimeCallback, localeName, (uint)dwFlags, (IntPtr)dataHandle);
#else
                // Now call the enumeration API. Work is done by our callback function
                IntPtr callback = AddrofIntrinsics.AddrOf <Func <IntPtr, IntPtr, Interop.BOOL> >(EnumTimeCallback);
                Interop.Kernel32.EnumTimeFormatsEx(callback, localeName, (uint)dwFlags, (IntPtr)dataHandle);
#endif
            }
            finally
            {
                dataHandle.Free();
            }

            if (data.strings.Count > 0)
            {
                // Now we need to allocate our stringarray and populate it
                string[] results = data.strings.ToArray();

                if (!useUserOverride && data.strings.Count > 1)
                {
                    // Since there is no "NoUserOverride" aware EnumTimeFormatsEx, we always get an override
                    // The override is the first entry if it is overriden.
                    // We can check if we have overrides by checking the GetLocaleInfo with no override
                    // If we do have an override, we don't know if it is a user defined override or if the
                    // user has just selected one of the predefined formats so we can't just remove it
                    // but we can move it down.
                    uint   lcType = (dwFlags == TIME_NOSECONDS) ? LOCALE_SSHORTTIME : LOCALE_STIMEFORMAT;
                    string timeFormatNoUserOverride = GetLocaleInfoFromLCType(localeName, lcType, useUserOverride);
                    if (timeFormatNoUserOverride != "")
                    {
                        string firstTimeFormat = results[0];
                        if (timeFormatNoUserOverride != firstTimeFormat)
                        {
                            results[0] = results[1];
                            results[1] = firstTimeFormat;
                        }
                    }
                }

                return(results);
            }

            return(null);
        }
コード例 #6
0
ファイル: ThreadPool.Unix.cs プロジェクト: tijoytom/corert
        internal static void QueueLongRunningWork(Action callback)
        {
            GCHandle gcHandle = GCHandle.Alloc(callback);

            if (!Interop.Sys.RuntimeThread_CreateThread(IntPtr.Zero /*use default stack size*/,
                                                        AddrofIntrinsics.AddrOf <Interop.Sys.ThreadProc>(LongRunningWorkCallback), GCHandle.ToIntPtr(gcHandle)))
            {
                gcHandle.Free();
                throw new OutOfMemoryException();
            }
        }
コード例 #7
0
        // Call native side to figure out which calendars are allowed
        internal static int GetCalendars(String localeName, bool useUserOverride, CalendarId[] calendars)
        {
            Debug.Assert(!GlobalizationMode.Invariant);

            EnumCalendarsData data = new EnumCalendarsData();

            data.userOverride = 0;
            data.calendars    = new IntList();

            // First call GetLocaleInfo if necessary
            if (useUserOverride)
            {
                // They want user overrides, see if the user calendar matches the input calendar
                int userCalendar = CultureData.GetLocaleInfoExInt(localeName, LOCALE_ICALENDARTYPE);

                // If we got a default, then use it as the first calendar
                if (userCalendar != 0)
                {
                    data.userOverride = userCalendar;
                    data.calendars.Add(userCalendar);
                }
            }

            GCHandle contextHandle = GCHandle.Alloc(data);

            try
            {
                // Now call the enumeration API. Work is done by our callback function
#if CORECLR
                Interop.Kernel32.EnumCalendarInfoExEx(EnumCalendarsCallback, localeName, ENUM_ALL_CALENDARS, null, CAL_ICALINTVALUE, (IntPtr)contextHandle);
#else
                IntPtr callback = AddrofIntrinsics.AddrOf <Func <IntPtr, uint, IntPtr, IntPtr, Interop.BOOL> >(EnumCalendarsCallback);
                Interop.Kernel32.EnumCalendarInfoExEx(callback, localeName, ENUM_ALL_CALENDARS, null, CAL_ICALINTVALUE, (IntPtr)contextHandle);
#endif
            }
            finally
            {
                contextHandle.Free();
            }

            // Copy to the output array
            for (int i = 0; i < Math.Min(calendars.Length, data.calendars.Count); i++)
            {
                calendars[i] = (CalendarId)data.calendars[i];
            }

            // Now we have a list of data, return the count
            return(data.calendars.Count);
        }
コード例 #8
0
ファイル: ThreadPool.Windows.cs プロジェクト: tijoytom/corert
        internal static unsafe void QueueLongRunningWork(Action callback)
        {
            var environ = default(Interop.mincore.TP_CALLBACK_ENVIRON);

            environ.Initialize();
            environ.SetLongFunction();

            IntPtr nativeCallback = AddrofIntrinsics.AddrOf <Interop.mincore.SimpleCallback>(LongRunningWorkCallback);

            GCHandle gcHandle = GCHandle.Alloc(callback);

            if (!Interop.mincore.TrySubmitThreadpoolCallback(nativeCallback, GCHandle.ToIntPtr(gcHandle), &environ))
            {
                gcHandle.Free();
                throw new OutOfMemoryException();
            }
        }
コード例 #9
0
        private bool CreateThread(GCHandle thisThreadHandle)
        {
            // Create the Stop event before starting the thread to make sure
            // it is ready to be signaled at thread shutdown time.
            // This also avoids OOM after creating the thread.
            _stopped = new ManualResetEvent(false);

            if (!Interop.Sys.RuntimeThread_CreateThread((IntPtr)_maxStackSize,
                                                        AddrofIntrinsics.AddrOf <Interop.Sys.ThreadProc>(ThreadEntryPoint), (IntPtr)thisThreadHandle))
            {
                return(false);
            }

            // CoreCLR ignores OS errors while setting the priority, so do we
            SetPriorityLive(_priority);

            return(true);
        }
コード例 #10
0
        private unsafe void SetTimer(uint actualDuration)
        {
            if (_nativeTimer == IntPtr.Zero)
            {
                IntPtr nativeCallback = AddrofIntrinsics.AddrOf <Interop.mincore.TimerCallback>(TimerCallback);

                _nativeTimer = Interop.mincore.CreateThreadpoolTimer(nativeCallback, IntPtr.Zero, IntPtr.Zero);
                if (_nativeTimer == IntPtr.Zero)
                {
                    throw new OutOfMemoryException();
                }
            }

            // Negative time indicates the amount of time to wait relative to the current time, in 100 nanosecond units
            long dueTime = -10000 * (long)actualDuration;

            Interop.mincore.SetThreadpoolTimer(_nativeTimer, &dueTime, 0, 0);
        }
コード例 #11
0
ファイル: ThreadPool.Unix.cs プロジェクト: weshaggard/corert
        /// <summary>
        /// This method is called to request a new thread pool worker to handle pending work.
        /// </summary>
        internal static void QueueDispatch()
        {
            // For simplicity of the state management, we pre-create all thread pool workers on the first
            // request and then use the semaphore to release threads as new requests come in.
            if ((s_workerCount == 0) && Interlocked.Exchange(ref s_workerCount, MaxThreadCount) == 0)
            {
                for (int i = 0; i < MaxThreadCount; i++)
                {
                    if (!Interop.Sys.RuntimeThread_CreateThread(IntPtr.Zero /*use default stack size*/,
                                                                AddrofIntrinsics.AddrOf <Interop.Sys.ThreadProc>(ThreadPoolDispatchCallback), IntPtr.Zero))
                    {
                        throw new OutOfMemoryException();
                    }
                }
            }

            // Release one thread to handle the new request
            s_semaphore.Release(1);
        }
コード例 #12
0
        // Call native side to figure out which calendars are allowed
        internal static int GetCalendars(String localeName, bool useUserOverride, CalendarId[] calendars)
        {
            EnumCalendarsData data = new EnumCalendarsData();

            data.userOverride = 0;
            data.calendars    = new LowLevelList <int>();

            // First call GetLocaleInfo if necessary
            if (useUserOverride)
            {
                // They want user overrides, see if the user calendar matches the input calendar
                int userCalendar = Interop.mincore.GetLocaleInfoExInt(localeName, LOCALE_ICALENDARTYPE);

                // If we got a default, then use it as the first calendar
                if (userCalendar != 0)
                {
                    data.userOverride = userCalendar;
                    data.calendars.Add(userCalendar);
                }
            }

            GCHandle contextHandle = GCHandle.Alloc(data);

            try
            {
                // Now call the enumeration API. Work is done by our callback function
                IntPtr callback = AddrofIntrinsics.AddrOf <Interop.mincore.EnumCalendarInfoProcExEx>(EnumCalendarsCallback);
                Interop.mincore.EnumCalendarInfoExEx(callback, localeName, ENUM_ALL_CALENDARS, null, CAL_ICALINTVALUE, (IntPtr)contextHandle);
            }
            finally
            {
                contextHandle.Free();
            }

            // Copy to the output array
            for (int i = 0; i < Math.Min(calendars.Length, data.calendars.Count); i++)
            {
                calendars[i] = (CalendarId)data.calendars[i];
            }

            // Now we have a list of data, return the count
            return(data.calendars.Count);
        }
コード例 #13
0
ファイル: ThreadPool.Windows.cs プロジェクト: tijoytom/corert
        internal static void QueueDispatch()
        {
            if (s_work == IntPtr.Zero)
            {
                IntPtr nativeCallback = AddrofIntrinsics.AddrOf <Interop.mincore.WorkCallback>(DispatchCallback);

                IntPtr work = Interop.mincore.CreateThreadpoolWork(nativeCallback, IntPtr.Zero, IntPtr.Zero);
                if (work == IntPtr.Zero)
                {
                    throw new OutOfMemoryException();
                }

                if (Interlocked.CompareExchange(ref s_work, work, IntPtr.Zero) != IntPtr.Zero)
                {
                    Interop.mincore.CloseThreadpoolWork(work);
                }
            }

            Interop.mincore.SubmitThreadpoolWork(s_work);
        }
コード例 #14
0
        private bool CreateThread(GCHandle thisThreadHandle)
        {
            const int AllocationGranularity = 0x10000;  // 64 KiB

            int stackSize = _maxStackSize;

            if ((0 < stackSize) && (stackSize < AllocationGranularity))
            {
                // If StackSizeParamIsAReservation flag is set and the reserve size specified by CreateThread's
                // dwStackSize parameter is less than or equal to the initially committed stack size specified in
                // the executable header, the reserve size will be set to the initially committed size rounded up
                // to the nearest multiple of 1 MiB. In all cases the reserve size is rounded up to the nearest
                // multiple of the system's allocation granularity (typically 64 KiB).
                //
                // To prevent overreservation of stack memory for small stackSize values, we increase stackSize to
                // the allocation granularity. We assume that the SizeOfStackCommit field of IMAGE_OPTIONAL_HEADER
                // is strictly smaller than the allocation granularity (the field's default value is 4 KiB);
                // otherwise, at least 1 MiB of memory will be reserved. Note that the desktop CLR increases
                // stackSize to 256 KiB if it is smaller than that.
                stackSize = AllocationGranularity;
            }

            uint threadId;

            _osHandle = Interop.Kernel32.CreateThread(IntPtr.Zero, (IntPtr)stackSize,
                                                      AddrofIntrinsics.AddrOf <Interop.Kernel32.ThreadProc>(ThreadEntryPoint), (IntPtr)thisThreadHandle,
                                                      Interop.Kernel32.CREATE_SUSPENDED | Interop.Kernel32.STACK_SIZE_PARAM_IS_A_RESERVATION,
                                                      out threadId);

            if (_osHandle.IsInvalid)
            {
                return(false);
            }

            // CoreCLR ignores OS errors while setting the priority, so do we
            SetPriorityLive(_priority);

            Interop.Kernel32.ResumeThread(_osHandle);
            return(true);
        }
コード例 #15
0
        private void StartCore(object parameter)
        {
            using (LockHolder.Hold(_lock))
            {
                if (!GetThreadStateBit(ThreadState.Unstarted))
                {
                    throw new ThreadStateException(SR.ThreadState_AlreadyStarted);
                }

                // TODO: OOM hardening, _maxStackSize
                GCHandle threadHandle = GCHandle.Alloc(this);
                _threadStartArg = parameter;

                try
                {
                    uint threadId;

                    _osHandle = new SafeWaitHandle(Interop.mincore.CreateThread(IntPtr.Zero, IntPtr.Zero,
                                                                                AddrofIntrinsics.AddrOf <Interop.mincore.ThreadProc>(StartThread), (IntPtr)threadHandle, 0, out threadId),
                                                   ownsHandle: true);

                    // Ignore errors (as in CoreCLR)
                    SetPriority(_priority);

                    // Wait until the new thread is started (as in CoreCLR)
                    while (GetThreadStateBit(ThreadState.Unstarted))
                    {
                        Yield();
                    }
                }
                finally
                {
                    if (_osHandle == null)
                    {
                        threadHandle.Free();
                        _threadStartArg = null;
                    }
                }
            }
        }
コード例 #16
0
        private void StartCore(object parameter)
        {
            using (LockHolder.Hold(_lock))
            {
                if (!GetThreadStateBit(ThreadState.Unstarted))
                {
                    throw new ThreadStateException(SR.ThreadState_AlreadyStarted);
                }

                const int AllocationGranularity = (int)0x10000; // 64k

                int stackSize = _maxStackSize;
                if ((0 < stackSize) && (stackSize < AllocationGranularity))
                {
                    // If StackSizeParamIsAReservation flag is set and the reserve size specified by CreateThread's
                    // dwStackSize parameter is less than or equal to the initially committed stack size specified in
                    // the executable header, the reserve size will be set to the initially committed size rounded up
                    // to the nearest multiple of 1 MiB. In all cases the reserve size is rounded up to the nearest
                    // multiple of the system's allocation granularity (typically 64 KiB).
                    //
                    // To prevent overreservation of stack memory for small stackSize values, we increase stackSize to
                    // the allocation granularity. We assume that the SizeOfStackCommit field of IMAGE_OPTIONAL_HEADER
                    // is strictly smaller than the allocation granularity (the field's default value is 4 KiB);
                    // otherwise, at least 1 MiB of memory will be reserved. Note that the desktop CLR increases
                    // stackSize to 256 KiB if it is smaller than that.
                    stackSize = AllocationGranularity;
                }

                bool     waitingForThreadStart = false;
                GCHandle threadHandle          = GCHandle.Alloc(this);
                _threadStartArg = parameter;
                uint threadId;

                try
                {
                    _osHandle = Interop.mincore.CreateThread(IntPtr.Zero, (IntPtr)stackSize,
                                                             AddrofIntrinsics.AddrOf <Interop.mincore.ThreadProc>(StartThread), (IntPtr)threadHandle,
                                                             (uint)(Interop.Constants.CreateSuspended | Interop.Constants.StackSizeParamIsAReservation),
                                                             out threadId);

                    // CoreCLR ignores OS errors while setting the priority, so do we
                    SetPriority(_priority);

                    Interop.mincore.ResumeThread(_osHandle);

                    // Skip cleanup if any asynchronous exception happens while waiting for the thread start
                    waitingForThreadStart = true;

                    // Wait until the new thread either dies or reports itself as started
                    while (GetThreadStateBit(ThreadState.Unstarted) && !HasFinishedExecution())
                    {
                        Yield();
                    }

                    waitingForThreadStart = false;
                }
                finally
                {
                    Debug.Assert(!waitingForThreadStart, "Leaked threadHandle");
                    if (!waitingForThreadStart)
                    {
                        threadHandle.Free();
                        _threadStartArg = null;
                    }
                }

                if (GetThreadStateBit(ThreadState.Unstarted))
                {
                    // Lack of memory is the only expected reason for thread creation failure
                    throw new ThreadStartException(new OutOfMemoryException());
                }
            }
        }
コード例 #17
0
 private void PlatformSpecificInitialize()
 {
     _waitInfo = new WaitSubsystem.ThreadWaitInfo(this);
     RuntimeImports.RhSetThreadExitCallback(AddrofIntrinsics.AddrOf <Action>(OnThreadExit));
 }
コード例 #18
0
 private void PlatformSpecificInitialize()
 {
     RuntimeImports.RhSetThreadExitCallback(AddrofIntrinsics.AddrOf <Action>(OnThreadExit));
 }
コード例 #19
0
        private static unsafe bool CallEnumCalendarInfo(string localeName, CalendarId calendar, uint calType, uint lcType, out string[] data)
        {
            EnumData context = new EnumData();

            context.userOverride = null;
            context.strings      = new StringList();
            // First call GetLocaleInfo if necessary
            if (((lcType != 0) && ((lcType & CAL_NOUSEROVERRIDE) == 0)) &&
                // Get user locale, see if it matches localeName.
                // Note that they should match exactly, including letter case
                GetUserDefaultLocaleName() == localeName)
            {
                // They want user overrides, see if the user calendar matches the input calendar
                CalendarId userCalendar = (CalendarId)CultureData.GetLocaleInfoExInt(localeName, LOCALE_ICALENDARTYPE);

                // If the calendars were the same, see if the locales were the same
                if (userCalendar == calendar)
                {
                    // They matched, get the user override since locale & calendar match
                    string res = CultureData.GetLocaleInfoEx(localeName, lcType);

                    // if it succeeded remember the override for the later callers
                    if (res != "")
                    {
                        // Remember this was the override (so we can look for duplicates later in the enum function)
                        context.userOverride = res;

                        // Add to the result strings.
                        context.strings.Add(res);
                    }
                }
            }

            GCHandle contextHandle = GCHandle.Alloc(context);

            try
            {
#if CORECLR
                Interop.Kernel32.EnumCalendarInfoExEx(EnumCalendarInfoCallback, localeName, (uint)calendar, null, calType, (IntPtr)contextHandle);
#else
                // Now call the enumeration API. Work is done by our callback function
                IntPtr callback = AddrofIntrinsics.AddrOf <Func <IntPtr, uint, IntPtr, IntPtr, Interop.BOOL> >(EnumCalendarInfoCallback);
                Interop.Kernel32.EnumCalendarInfoExEx(callback, localeName, (uint)calendar, null, calType, (IntPtr)contextHandle);
#endif // CORECLR
            }
            finally
            {
                contextHandle.Free();
            }

            // Now we have a list of data, fail if we didn't find anything.
            if (context.strings.Count == 0)
            {
                data = null;
                return(false);
            }

            string[] output = context.strings.ToArray();

            if (calType == CAL_SABBREVERASTRING || calType == CAL_SERASTRING)
            {
                // Eras are enumerated backwards.  (oldest era name first, but
                // Japanese calendar has newest era first in array, and is only
                // calendar with multiple eras)
                Array.Reverse(output, 0, output.Length);
            }

            data = output;

            return(true);
        }