internal DispatchCellInfo ConvertDispatchCellInfo(IntPtr module, DispatchCellInfo cellInfo) { using (LockHolder.Hold(_typeLoaderLock)) { return ConvertDispatchCellInfo_Inner( module, cellInfo); } }
internal DispatchCellInfo ConvertDispatchCellInfo(NativeFormatModuleInfo module, DispatchCellInfo cellInfo) { using (LockHolder.Hold(_typeLoaderLock)) { return ConvertDispatchCellInfo_Inner( module, cellInfo); } }
public bool TryGetGenericMethodDictionaryForComponents(RuntimeTypeHandle declaringTypeHandle, RuntimeTypeHandle[] genericMethodArgHandles, MethodNameAndSignature nameAndSignature, out IntPtr methodDictionary) { if (TryLookupGenericMethodDictionaryForComponents(declaringTypeHandle, nameAndSignature, genericMethodArgHandles, out methodDictionary)) return true; using (LockHolder.Hold(_typeLoaderLock)) { return TypeBuilder.TryBuildGenericMethod(declaringTypeHandle, genericMethodArgHandles, nameAndSignature, out methodDictionary); } }
//-------------------------------------------------------------------------------------------- // Gets an enumerator for the table. The returned enumerator will not extend the lifetime of // any object pairs in the table, other than the one that's Current. It will not return entries // that have already been collected, nor will it return entries added after the enumerator was // retrieved. It may not return all entries that were present when the enumerat was retrieved, // however, such as not returning entries that were collected or removed after the enumerator // was retrieved but before they were enumerated. //-------------------------------------------------------------------------------------------- IEnumerator <KeyValuePair <TKey, TValue> > IEnumerable <KeyValuePair <TKey, TValue> > .GetEnumerator() { using (LockHolder.Hold(_lock)) { Container c = _container; return(c == null || c.FirstFreeEntry == 0 ? ((IEnumerable <KeyValuePair <TKey, TValue> >)Array.Empty <KeyValuePair <TKey, TValue> >()).GetEnumerator() : new Enumerator(this)); } }
public bool TryGetConstructedGenericTypeForComponents(RuntimeTypeHandle genericTypeDefinitionHandle, RuntimeTypeHandle[] genericTypeArgumentHandles, out RuntimeTypeHandle runtimeTypeHandle) { if (TryLookupConstructedGenericTypeForComponents(genericTypeDefinitionHandle, genericTypeArgumentHandles, out runtimeTypeHandle)) return true; using (LockHolder.Hold(_typeLoaderLock)) { return TypeBuilder.TryBuildGenericType(genericTypeDefinitionHandle, genericTypeArgumentHandles, out runtimeTypeHandle); } }
public bool TryDispatchMethodOnTarget(NativeFormatModuleInfo module, int metadataToken, RuntimeTypeHandle targetInstanceType, out IntPtr methodAddress) { using (LockHolder.Hold(_typeLoaderLock)) { return TryDispatchMethodOnTarget_Inner( module, metadataToken, targetInstanceType, out methodAddress); } }
// // Retrieve the *unique* value for a given key. If the key was previously not entered into the dictionary, // this method invokes the overridable Factory() method to create the new value. The Factory() method is // invoked outside of any locks. If two threads race to enter a value for the same key, the Factory() // may get invoked twice for the same key - one of them will "win" the race and its result entered into the // dictionary - other gets thrown away. // public V GetOrAdd(K key) { Debug.Assert(key != null); Debug.Assert(!_lock.IsAcquired, "GetOrAdd called while lock already acquired. A possible cause of this is an Equals or GetHashCode method that causes reentrancy in the table."); int hashCode = key.GetHashCode(); V value; bool found = _container.TryGetValue(key, hashCode, out value); #if DEBUG { V checkedValue; bool checkedFound; // In debug builds, always exercise a locked TryGet (this is a good way to detect deadlock/reentrancy through Equals/GetHashCode()). using (LockHolder.Hold(_lock)) { _container.VerifyUnifierConsistency(); int h = key.GetHashCode(); checkedFound = _container.TryGetValue(key, h, out checkedValue); } if (found) { // State of a key must never go from found to not found, and only one value may exist per key. Debug.Assert(checkedFound); if (default(V) == null) // No good way to do the "only one value" check for value types. { Debug.Assert(Object.ReferenceEquals(checkedValue, value)); } } } #endif //DEBUG if (found) { return(value); } value = this.Factory(key); using (LockHolder.Hold(_lock)) { V heyIWasHereFirst; if (_container.TryGetValue(key, hashCode, out heyIWasHereFirst)) { return(heyIWasHereFirst); } if (!_container.HasCapacity) { _container.Resize(); // This overwrites the _container field. } _container.Add(key, hashCode, value); return(value); } }
/// <summary>Informs the scheduler pair that it should not accept any more tasks.</summary> /// <remarks> /// Calling <see cref="Complete"/> is optional, and it's only necessary if the <see cref="Completion"/> /// will be relied on for notification of all processing being completed. /// </remarks> public void Complete() { using (LockHolder.Hold(ValueLock)) { if (!CompletionRequested) { RequestCompletion(); CleanupStateIfCompletingAndQuiesced(); } } }
public void StartServiceExecution() { try { currentState = State.Running; while (currentState == State.Running) { if (!connectionActive) { connectionActive = true; EventLogger.DebugEntry("Main-Loop", EventLogEntryType.Information); IPAddress ipAd = IPAddress.Parse(Properties.Settings.Default.IPAddress); myList = new TcpListener(ipAd, 19358); myList.Start(); s = myList.AcceptSocket(); byte[] b = new byte[100]; int k = s.Receive(b); if (compareBytes(b, GetBytes("startScan", 100))) { CheckForRun(); } } EventLogger.DebugEntry("Main-Loop - Sleep", EventLogEntryType.Information); } while (currentState == State.Shutting_Down) { using (LockHolder <Dictionary <Guid, ThreadHolder> > lockObj = new LockHolder <Dictionary <Guid, ThreadHolder> >(runningThreads, 1000)) { if (lockObj.LockSuccessful) { foreach (ThreadHolder currentThread in runningThreads.Values) { // Now break the processing of the complex thread currentThread.scanThread.BreakOperation(); } // If no more threads are left, set the state to stopped if (runningThreads.Count == 0) { currentState = State.Stopped; } } } } } catch (Exception e) { EventLogger.Entry("Service Error: " + e, EventLogEntryType.Error); } }
//-------------------------------------------------------------------------------------------- // key: key to remove. May not be null. // // Returns true if the key is found and removed. Returns false if the key was not in the dictionary. // // Note: The key may get garbage collected during the Remove() operation. If so, // Remove() will not fail or throw, however, the return value can be either true or false // depending on who wins the race. //-------------------------------------------------------------------------------------------- public bool Remove(TKey key) { if (key == null) { throw new ArgumentNullException("key"); } using (LockHolder.Hold(_lock)) { return(_container.Remove(key)); } }
public bool TryGetFieldOffset(RuntimeTypeHandle declaringTypeHandle, uint fieldOrdinal, out int fieldOffset) { fieldOffset = int.MinValue; // No use going further for non-generic types... TypeLoader doesn't have offset answers for non-generic types! if (!declaringTypeHandle.IsGenericType()) return false; using (LockHolder.Hold(_typeLoaderLock)) { return TypeBuilder.TryGetFieldOffset(declaringTypeHandle, fieldOrdinal, out fieldOffset); } }
/// <summary> /// Processes exclusive tasks serially until either there are no more to process /// or we've reached our user-specified maximum limit. /// </summary> private void ProcessExclusiveTasks() { Debug.Assert(m_processingCount == EXCLUSIVE_PROCESSING_SENTINEL, "Processing exclusive tasks requires being in exclusive mode."); Debug.Assert(!m_exclusiveTaskScheduler.m_tasks.IsEmpty, "Processing exclusive tasks requires tasks to be processed."); ContractAssertMonitorStatus(ValueLock, held: false); try { // Note that we're processing exclusive tasks on the current thread Debug.Assert(m_threadProcessingMode.Value == ProcessingMode.NotCurrentlyProcessing, "This thread should not yet be involved in this pair's processing."); m_threadProcessingMode.Value = ProcessingMode.ProcessingExclusiveTask; // Process up to the maximum number of items per task allowed for (int i = 0; i < m_maxItemsPerTask; i++) { // Get the next available exclusive task. If we can't find one, bail. Task exclusiveTask; if (!m_exclusiveTaskScheduler.m_tasks.TryDequeue(out exclusiveTask)) { break; } // Execute the task. If the scheduler was previously faulted, // this task could have been faulted when it was queued; ignore such tasks. if (!exclusiveTask.IsFaulted) { m_exclusiveTaskScheduler.ExecuteTask(exclusiveTask); } } } finally { // We're no longer processing exclusive tasks on the current thread Debug.Assert(m_threadProcessingMode.Value == ProcessingMode.ProcessingExclusiveTask, "Somehow we ended up escaping exclusive mode."); m_threadProcessingMode.Value = ProcessingMode.NotCurrentlyProcessing; using (LockHolder.Hold(ValueLock)) { // When this task was launched, we tracked it by setting m_processingCount to WRITER_IN_PROGRESS. // now reset it to 0. Then check to see whether there's more processing to be done. // There might be more concurrent tasks available, for example, if concurrent tasks arrived // after we exited the loop, or if we exited the loop while concurrent tasks were still // available but we hit our maxItemsPerTask limit. Debug.Assert(m_processingCount == EXCLUSIVE_PROCESSING_SENTINEL, "The processing mode should not have deviated from exclusive."); m_processingCount = 0; ProcessAsyncIfNecessary(true); } } }
//////////////////////////////////////////////////////////// // // Internal methods // // This is called by the TaskExceptionHolder finalizer. internal static void PublishUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs ueea) { // Lock this logic to prevent just-unregistered handlers from being called. using (LockHolder.Hold(_unobservedTaskExceptionLockObject)) { // Since we are under lock, it is technically no longer necessary // to make a copy. It is done here for convenience. EventHandler <UnobservedTaskExceptionEventArgs> handler = _unobservedTaskException; if (handler != null) { handler(sender, ueea); } } }
public void ThreadFinished(Guid threadId) { EventLogger.DebugEntry("Thread closing start", EventLogEntryType.Information); using (LockHolder <Dictionary <Guid, ThreadHolder> > lockObj = new LockHolder <Dictionary <Guid, ThreadHolder> >(runningThreads, 1000)) { if (lockObj.LockSuccessful) { isProcessing = false; runningThreads.Remove(threadId); } } EventLogger.DebugEntry("Thread closing end", EventLogEntryType.Information); }
public unsafe IntPtr GetMemoryBlockForValue(ThreadStaticFieldOffsets value) { using (LockHolder.Hold(_lock)) { IntPtr result; if (_allocatedBlocks.TryGetValue(value, out result)) { return(result); } result = MemoryHelpers.AllocateMemory(sizeof(ThreadStaticFieldOffsets)); *(ThreadStaticFieldOffsets *)(result.ToPointer()) = value; _allocatedBlocks.Add(value, result); return(result); } }
public unsafe IntPtr GetMemoryBlockForValue(IntPtr value) { using (LockHolder.Hold(_lock)) { IntPtr result; if (_allocatedBlocks.TryGetValue(value, out result)) { return(result); } result = MemoryHelpers.AllocateMemory(IntPtr.Size); *(IntPtr *)(result.ToPointer()) = value; _allocatedBlocks.Add(value, result); return(result); } }
private IntPtr TryGetTlsOffsetDictionaryCellForDynamicType(RuntimeTypeHandle runtimeTypeHandle) { Debug.Assert(runtimeTypeHandle.IsDynamicType()); using (LockHolder.Hold(_threadStaticsLock)) { uint offsetValue; if (_dynamicGenericsThreadStatics.TryGetValue(runtimeTypeHandle, out offsetValue)) { return(TryCreateDictionaryCellWithValue(offsetValue)); } } return(IntPtr.Zero); }
public bool TryGetByRefTypeForTargetType(RuntimeTypeHandle pointeeTypeHandle, out RuntimeTypeHandle byRefTypeHandle) { // There are no lookups for ByRefs in static modules. All ByRef EETypes will be created at this level. // It's possible to have multiple ByRef EETypes representing the same ByRef type with the same element type // The caching of ByRef types is done at the reflection layer (in the RuntimeTypeUnifier) and // here in the TypeSystemContext layer if (TypeSystemContext.ByRefTypesCache.TryGetValue(pointeeTypeHandle, out byRefTypeHandle)) return true; using (LockHolder.Hold(_typeLoaderLock)) { return TypeBuilder.TryBuildByRefType(pointeeTypeHandle, out byRefTypeHandle); } }
private void StartInternal(object parameter) { using (LockHolder.Hold(_lock)) { if (!GetThreadStateBit(ThreadState.Unstarted)) { throw new ThreadStateException(SR.ThreadState_AlreadyStarted); } bool waitingForThreadStart = false; GCHandle threadHandle = GCHandle.Alloc(this); _threadStartArg = parameter; try { if (!CreateThread(threadHandle)) { throw new OutOfMemoryException(); } // 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) && !JoinInternal(0)) { 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()); } } }
/// <summary> /// Register all modules which were added (Registered) to the runtime and are not already registered with the TypeLoader. /// </summary> /// <param name="moduleType">Type to assign to all new modules.</param> public void RegisterNewModules(ModuleType moduleType) { // prevent multiple threads from registering modules concurrently using (LockHolder.Hold(_moduleRegistrationLock)) { // Fetch modules that have already been registered with the runtime int loadedModuleCount = RuntimeAugments.GetLoadedModules(null); IntPtr[] loadedModuleHandles = new IntPtr[loadedModuleCount]; int loadedModuleCountUpdated = RuntimeAugments.GetLoadedModules(loadedModuleHandles); Debug.Assert(loadedModuleCount == loadedModuleCountUpdated); LowLevelList <IntPtr> newModuleHandles = new LowLevelList <IntPtr>(loadedModuleHandles.Length); foreach (IntPtr moduleHandle in loadedModuleHandles) { // Skip already registered modules. int oldModuleIndex; if (_loadedModuleMap.HandleToModuleIndex.TryGetValue(moduleHandle, out oldModuleIndex)) { continue; } newModuleHandles.Add(moduleHandle); } // Copy existing modules to new dictionary int oldModuleCount = _loadedModuleMap.Modules.Length; ModuleInfo[] updatedModules = new ModuleInfo[oldModuleCount + newModuleHandles.Count]; if (oldModuleCount > 0) { Array.Copy(_loadedModuleMap.Modules, 0, updatedModules, 0, oldModuleCount); } for (int newModuleIndex = 0; newModuleIndex < newModuleHandles.Count; newModuleIndex++) { ModuleInfo newModuleInfo = new ModuleInfo(newModuleHandles[newModuleIndex], moduleType); updatedModules[oldModuleCount + newModuleIndex] = newModuleInfo; if (_moduleRegistrationCallbacks != null) { _moduleRegistrationCallbacks(newModuleInfo); } } // Atomically update the module map _loadedModuleMap = new ModuleMap(updatedModules); } }
public void FreeLock(LockHolder current) { lock (this) { if (current != Owner) { throw new InvalidOperationException("dude wtf how could this happen"); } Owner = null; if (Queue.Count > 0) { var next = Queue.First.Value; Queue.RemoveFirst(); ScheduleAwaitable(next); } } }
public void ThreadFinished(Guid threadId) { EventLogger.DebugEntry("Thread closing start", EventLogEntryType.Information); using (LockHolder <Dictionary <Guid, ThreadHolder> > lockObj = new LockHolder <Dictionary <Guid, ThreadHolder> >(runningThreads, 1000)) { if (lockObj.LockSuccessful) { nextRun = DateTime.Now.AddSeconds(Properties.Settings.Default.trigger_thread); isProcessing = false; runningThreads.Remove(threadId); } } EventLogger.DebugEntry("Thread closing end", EventLogEntryType.Information); }
/// <summary>Queues a task to the scheduler.</summary> /// <param name="task">The task to be queued.</param> protected internal override void QueueTask(Task task) { Debug.Assert(task != null, "Infrastructure should have provided a non-null task."); using (LockHolder.Hold(m_pair.ValueLock)) { // If the scheduler has already had completion requested, no new work is allowed to be scheduled if (m_pair.CompletionRequested) { throw new InvalidOperationException(GetType().ToString()); } // Queue the task, and then let the pair know that more work is now available to be scheduled m_tasks.Enqueue(task); m_pair.ProcessAsyncIfNecessary(); } }
public static void Release(CctorHandle cctor) { using (LockHolder.Hold(s_cctorGlobalLock)) { Cctor[] cctors = cctor.Array; int cctorIndex = cctor.Index; if (0 == Interlocked.Decrement(ref cctors[cctorIndex]._refCount)) { if (cctors[cctorIndex].Exception == null) { cctors[cctorIndex] = default; s_count--; } } } }
/// <summary> /// Attempt to acquire a lock on the queue to mark it as in-use. /// </summary> /// <param name="lockObject">If locking the queue for use was /// successful (returned true), lockObject is an IDisposable that /// will discard the lock when disposed.</param> /// <returns>True if the queue is now marked as in-use, false if the /// queue could not be marked as in-use due to being blocked (or /// one of its lockqueues was in-use).</returns> public bool TryLock(out IDisposable lockObject) { Log.Info(string.Format(System.Globalization.CultureInfo.CurrentCulture, "Queue: '{0}' is attempting to be in-use, trying to lock related queues", Name)); lockObject = null; lock (blockingLockObject) { if (IsBlocked) { Log.Info(string.Format(System.Globalization.CultureInfo.CurrentCulture, "Queue: '{0}' is locked and cannot be in-use", Name)); return(false); } IList <IIntegrationQueue> lockedQueues = new List <IIntegrationQueue>(); bool failed = false; foreach (IIntegrationQueue queue in LockQueues) { if (queue.BlockQueue(this)) { Log.Info(string.Format(System.Globalization.CultureInfo.CurrentCulture, "Queue: '{0}' has acquired a lock against queue '{1}'", Name, queue.Name)); lockedQueues.Add(queue); } else { Log.Info(string.Format(System.Globalization.CultureInfo.CurrentCulture, "Queue: '{0}' has FAILED to acquire a lock against queue '{1}'", Name, queue.Name)); failed = true; break; } } if (failed) { foreach (IIntegrationQueue queue in lockedQueues) { Log.Info(string.Format(System.Globalization.CultureInfo.CurrentCulture, "Queue: '{0}' has released a lock against queue '{1}'", Name, queue.Name)); queue.UnblockQueue(this); return(false); } } lockObject = new LockHolder(this, lockedQueues); inUse = true; return(true); } }
public bool TryResolveSingleMetadataFixup(ModuleInfo module, int metadataToken, MetadataFixupKind fixupKind, out IntPtr fixupResolution) { using (LockHolder.Hold(_typeLoaderLock)) { try { return(TypeBuilder.TryResolveSingleMetadataFixup((NativeFormatModuleInfo)module, metadataToken, fixupKind, out fixupResolution)); } catch (Exception ex) { Environment.FailFast("Failed to resolve metadata token " + ((uint)metadataToken).LowLevelToString() + ": " + ex.Message); fixupResolution = IntPtr.Zero; return(false); } } }
public int TryGetThreadStaticsSizeForDynamicType(int index, out int numTlsCells) { Debug.Assert((index & DynamicTypeTlsOffsetFlag) == DynamicTypeTlsOffsetFlag); numTlsCells = _maxTlsCells; using (LockHolder.Hold(_threadStaticsLock)) { int storageSize; if (_dynamicGenericsThreadStaticSizes.TryGetValue((uint)index, out storageSize)) { return(storageSize); } } Debug.Assert(false); return(0); }
//-------------------------------------------------------------------------------------------- // key: key to add. May not be null. // value: value to associate with key. // // If the key is already entered into the dictionary, this method throws an exception. // // Note: The key may get garbage collected during the Add() operation. If so, Add() // has the right to consider any prior entries successfully removed and add a new entry without // throwing an exception. //-------------------------------------------------------------------------------------------- public void Add(TKey key, TValue value) { if (key == null) { throw new ArgumentNullException("key"); } using (LockHolder.Hold(_lock)) { object otherValue; int entryIndex = _container.FindEntry(key, out otherValue); if (entryIndex != -1) { throw new ArgumentException(SR.Format(SR.Argument_AddingDuplicate, key)); } CreateEntry(key, value); } }
public void RegisterModule(ModuleInfo newModuleInfo) { // prevent multiple threads from registering modules concurrently using (LockHolder.Hold(_moduleRegistrationLock)) { // Copy existing modules to new dictionary int oldModuleCount = _loadedModuleMap.Modules.Length; ModuleInfo[] updatedModules = new ModuleInfo[oldModuleCount + 1]; if (oldModuleCount > 0) { Array.Copy(_loadedModuleMap.Modules, 0, updatedModules, 0, oldModuleCount); } updatedModules[oldModuleCount] = newModuleInfo; _moduleRegistrationCallbacks?.Invoke(newModuleInfo); // Atomically update the module map _loadedModuleMap = new ModuleMap(updatedModules); } }
public unsafe bool TryGetOrCreateNamedTypeForMetadata( QTypeDefinition qTypeDefinition, out RuntimeTypeHandle runtimeTypeHandle) { if (TryGetNamedTypeForMetadata(qTypeDefinition, out runtimeTypeHandle)) { return true; } #if SUPPORTS_NATIVE_METADATA_TYPE_LOADING using (LockHolder.Hold(_typeLoaderLock)) { IntPtr runtimeTypeHandleAsIntPtr; TypeBuilder.ResolveSingleTypeDefinition(qTypeDefinition, out runtimeTypeHandleAsIntPtr); runtimeTypeHandle = *(RuntimeTypeHandle*)&runtimeTypeHandleAsIntPtr; return true; } #else return false; #endif }
/// <summary> /// Attempt to acquire a lock on the queue to mark it as in-use. /// </summary> /// <param name="lockObject">If locking the queue for use was /// successful (returned true), lockObject is an IDisposable that /// will discard the lock when disposed.</param> /// <returns>True if the queue is now marked as in-use, false if the /// queue could not be marked as in-use due to being blocked (or /// one of its lockqueues was in-use).</returns> public bool TryLock(out IDisposable lockObject) { Log.Info(string.Format(System.Globalization.CultureInfo.CurrentCulture,"Queue: '{0}' is attempting to be in-use, trying to lock related queues", Name)); lockObject = null; lock (blockingLockObject) { if (IsBlocked) { Log.Info(string.Format(System.Globalization.CultureInfo.CurrentCulture,"Queue: '{0}' is locked and cannot be in-use", Name)); return false; } IList<IIntegrationQueue> lockedQueues = new List<IIntegrationQueue>(); bool failed = false; foreach (IIntegrationQueue queue in LockQueues) { if (queue.BlockQueue(this)) { Log.Info(string.Format(System.Globalization.CultureInfo.CurrentCulture,"Queue: '{0}' has acquired a lock against queue '{1}'", Name, queue.Name)); lockedQueues.Add(queue); } else { Log.Info(string.Format(System.Globalization.CultureInfo.CurrentCulture,"Queue: '{0}' has FAILED to acquire a lock against queue '{1}'", Name, queue.Name)); failed = true; break; } } if (failed) { foreach (IIntegrationQueue queue in lockedQueues) { Log.Info(string.Format(System.Globalization.CultureInfo.CurrentCulture,"Queue: '{0}' has released a lock against queue '{1}'", Name, queue.Name)); queue.UnblockQueue(this); return false; } } lockObject = new LockHolder(this, lockedQueues); inUse = true; return true; } }