Example #1
0
 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);
     }
 }
Example #3
0
        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));
     }
 }
Example #5
0
        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);
            }
        }
Example #6
0
 public bool TryDispatchMethodOnTarget(NativeFormatModuleInfo module, int metadataToken, RuntimeTypeHandle targetInstanceType, out IntPtr methodAddress)
 {
     using (LockHolder.Hold(_typeLoaderLock))
     {
         return TryDispatchMethodOnTarget_Inner(
             module,
             metadataToken,
             targetInstanceType,
             out methodAddress);
     }
 }
Example #7
0
        //
        // 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();
         }
     }
 }
Example #9
0
        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);
            }
        }
Example #10
0
        //--------------------------------------------------------------------------------------------
        // 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));
            }
        }
Example #11
0
        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);
                }
            }
        }
Example #13
0
        ////////////////////////////////////////////////////////////
        //
        // 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);
                }
            }
        }
Example #14
0
        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);
     }
 }
Example #17
0
        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);
        }
Example #18
0
        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);
            }
        }
Example #19
0
        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());
                }
            }
        }
Example #20
0
        /// <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);
         }
     }
 }
Example #22
0
        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();
                }
            }
Example #24
0
 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--;
             }
         }
     }
 }
Example #25
0
        /// <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);
            }
        }
Example #26
0
 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);
         }
     }
 }
Example #27
0
        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);
        }
Example #28
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);
            }
        }
Example #29
0
        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);
            }
        }
Example #30
0
        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;
            }
        }