Inheritance: IDisposable
        public void TestAbortThread()
        {
            Lock sync = new Lock();
            TimedCondition aborted = new TimedCondition(sync);
            Thread testThread = new Thread(delegate()
            {
                try
                {
                    Log("Test thread sleeping for 8 seconds..");
                    Thread.Sleep(8000);
                }
                catch (ThreadAbortException)
                {
                    Log("Test thread aborted..");
                    aborted.Signal();
                }
                Fail("This line should never be executed");
            });
            testThread.Start();
            sync.Acquire();
            Log("Aborting test thread in 2 seconds.  Sleeping...");
            Thread.Sleep(2000);
            Log("...awake!  Going to abort the test thread.");
            testThread.Abort();
            Log("Called testThread.Abort()");

            try
            {
                aborted.Await(12000);
            }
            catch (ConditionTimedOutException)
            {
                Fail("Thread was not aborted as expected!");
            }
        }
Beispiel #2
0
 public void Only_one_thread_can_acquire_the_lock_at_a_time()
 {
     var l = new Lock<int>(1);
     var trigger = new ManualResetEvent(false);
     var first = Async.Fork(() =>
     {
         trigger.WaitOne();
         Thread.Sleep(200);
         l.Capture(new Result()).Wait();
     }, new Result());
     Result secondInternal = null;
     var second = Async.Fork(() =>
     {
         trigger.WaitOne();
         secondInternal = l.Capture(new Result());
     }, new Result());
     trigger.Set();
     Assert.IsFalse(first.HasValue);
     second.Wait();
     l.Release();
     Assert.IsTrue(secondInternal.HasValue);
     Assert.IsFalse(first.HasValue);
     secondInternal.Wait();
     first.Wait();
     Assert.IsTrue(first.HasValue);
 }
 public GlobalCacheEntity()
 {
     _readCount = 0;
     _lock = Lock.None;
     _isDeleted = false;
     _blockThreads = new Queue<Thread>();
 }
        public override void PerformTest()
        {
            Log("Creating " + _numberOfThreads + " threads");
            Thread[] threads = new Thread[_numberOfThreads];
            for (int i = 0; i < _numberOfThreads; i++)
            {
                threads[i] = new Thread(Work, ThreadPriority.Normal);
            }

            _startedThreads = 0;
            _startedThreadsLock = new Lock();
            _allThreadsStartedLock = new Lock();
            _allThreadsStartedCondition = new Condition(_allThreadsStartedLock);
            _allThreadsStartedLock.Acquire();

            Log("Starting " + _numberOfThreads + " threads"); // TODO: ParametizedThreadStart doesn't work properly
            for (int i = 0; i < _numberOfThreads; i++)
            {
                threads[i].Start();
            }

            // wait for all threads to be running
            _allThreadsStartedCondition.Await();
            _allThreadsStartedLock.Release();

            Log("Waiting for all threads to finish");

            _semaphore.Acquire(_numberOfThreads); // wait for all threads to finish

            Assert(_failedThreads + " threads failed the calculation", _failedThreads == 0);
            Log("All " + _numberOfThreads + " threads finished");

        }
Beispiel #5
0
 public static LockHolder Hold(Lock l)
 {
     LockHolder h;
     l.Acquire();
     h._lock = l;
     return h;
 }
 public MultiThreadingStressTest(int numberOfThreads)
     : base("Multi-threading stress test")
 {
     if (numberOfThreads < 2)
     {
         throw new ArgumentException("numberOfThreads should be greater than 1");
     }
     _threadFinishedLock = new Lock();
     _semaphore = new Semaphore(numberOfThreads);
     _numberOfThreads = numberOfThreads;
     _failedThreads = 0;
 }
 public GlobalCacheEntity(object value)
 {
     Value = value;
     Version = DateTime.UtcNow.Ticks;
     _readCount = 0;
     _lock = Lock.None;
     _blockThreads = new Queue<Thread>();
     ForeignKeys = new Dictionary<string, object>();
     ObjectId = Guid.NewGuid();
     _isDeleted = false;
     _writeLockThreadId = -1;
     _referenceCount = 0;
 }
Beispiel #8
0
 public void WhenDone_is_called_when_lock_is_acquired()
 {
     var l = new Lock<int>(1);
     var first = l.Capture(new Result());
     var second = l.Capture(new Result());
     Assert.IsTrue(first.HasValue);
     Assert.IsFalse(second.HasValue);
     var reset = new ManualResetEvent(false);
     second.WhenDone( _ => reset.Set());
     l.Release();
     Assert.IsTrue(reset.WaitOne(TimeSpan.FromSeconds(10),true));
     Assert.IsTrue(second.HasValue);
     l.Release();
 }
Beispiel #9
0
        public override void PerformTest()
        {
            _mainLock = new Lock();

            Thread controllerThread = new Thread(ControllerThreadStart, ThreadPriority.Normal);
            controllerThread.Name = "Controller Thread";

            controllerThread.Start();
            Thread.Sleep(2000);

            Log("Main thread is trying to acquire the main lock...");
            _mainLock.Acquire();
            Log("Main thread got the main lock...");
        }
Beispiel #10
0
        public object Call(string method, object[] args, int timeout)
        {
            XmlHttpRequest xhr = XmlHttpRequestManager.GetXmlHttpRequest();
            Lock l = new Lock();
            l.Acquire();
            TimedCondition condition = new TimedCondition(l);
            OnReadyStateChangeHandler handler = new OnReadyStateChangeHandler(xhr, condition);
            xhr.OnReadyStateChange = (NativeFunction)new VoidDelegate(handler.OnReadyStateChange);
            xhr.Open("POST", ServerUrl, true, Username, Password);
            xhr.SetRequestHeader(RpcMethodRequestHeader, method);
            xhr.Send(Serialize(args));
            if (timeout > 0)
            {
                try
                {
                    // wait for timeout milliseconds
                    condition.Await(timeout);
                }
                catch (ConditionTimedOutException)
                {
                    Logging.Debug("Request timed out!!!");
                    throw new JsonRpcCallTimedOutException(this, method, args, timeout);
                }
            }
            else
            {
                // wait indefinitely
                condition.Await();
            }

            // we have a response from the server, or we couldn't connect
            Logging.Debug("Status code is: " + xhr.Status);
            if (xhr.Status == 200)
            {
                Logging.Debug("Got 200! Response text is " + xhr.ResponseText);
                return Deserialize(xhr.ResponseText);
            }
            else if (xhr.Status == 0)
            {
                Logging.Debug("Request timed out!!!");
                throw new JsonRpcCallTimedOutException(this, method, args, 1000); // TODO: Extract into constant of 1000 ms.  Also this should be some sort of connection refused exception instead
            }
            else
            {
                throw GenerateException(xhr.Status, method, args, xhr.ResponseText);
            }
        }
        public void TestAbortThreadWithState()
        {
            Lock sync = new Lock();
            TimedCondition aborted = new TimedCondition(sync);
            Thread testThread = new Thread(delegate()
            {
                try
                {
                    Log("Test thread sleeping for 8 seconds..");
                    Thread.Sleep(8000);
                }
                catch (ThreadAbortException e)
                {
                    if (e.ExceptionState != null && e.ExceptionState.ToString() == "Exception state")
                    {
                        Log("Test thread aborted with state: " + e.ExceptionState);
                        aborted.Signal();
                    }
                    else
                    {
                        Log("Test thread aborted with unknown state: " + e.ExceptionState);
                    }
                }
                Fail("This line should never be executed");
            });
            testThread.Start();
            sync.Acquire();
            Log("Aborting test thread in 2 seconds");
            Thread.Sleep(2000);
            testThread.Abort("Exception state");

            try
            {
                aborted.Await(12000);
            }
            catch (ConditionTimedOutException)
            {
                Fail("Thread was not aborted as expected!");
            }
        }
Beispiel #12
0
        /// <summary>
        /// Helper to ensure the lock object is created before first use.
        /// </summary>
        private void EnsureLockObjectCreated()
        {
            Contract.Ensures(m_lock != null);
            Contract.Ensures(m_condition != null);

            if (m_lock == null)
            {
                Lock newObj = new Lock();
                Interlocked.CompareExchange(ref m_lock, newObj, null); // failure is benign.. someone else won the race.
            }

            if (m_condition == null)
            {
                Condition newCond = new Condition(m_lock);
                Interlocked.CompareExchange(ref m_condition, newCond, null);
            }
        }
Beispiel #13
0
        /// <summary>
        /// Register initially (eagerly) loaded modules.
        /// </summary>
        internal ModuleList()
        {
            _loadedModuleMap = new ModuleMap(new ModuleInfo[0]);
            _moduleRegistrationCallbacks = default(Action<ModuleInfo>);
            _moduleRegistrationLock = new Lock();

            RegisterNewModules(ModuleType.Eager);
        }
Beispiel #14
0
 public Condition(Lock @lock)
 {
     if (@lock == null)
         throw new ArgumentNullException("lock");
     _lock = @lock;
 }
Beispiel #15
0
        private static bool TryAcquireContended(Lock lck, Object obj, int millisecondsTimeout)
        {
#if FEATURE_GET_BLOCKING_OBJECTS
            int removeCookie = t_blockingObjects.Add(obj, ReasonForBlocking.OnCrst);
            try
            {
                return lck.TryAcquire(millisecondsTimeout);
            }
            finally
            {
                t_blockingObjects.Remove(removeCookie);
            }
#else
            return lck.TryAcquire(millisecondsTimeout);
#endif
        }
Beispiel #16
0
        internal readonly Codec Codec; // for writing new segments

        /// <summary>
        /// Constructs a new IndexWriter per the settings given in <code>conf</code>.
        /// If you want to make "live" changes to this writer instance, use
        /// <seealso cref="#getConfig()"/>.
        ///
        /// <p>
        /// <b>NOTE:</b> after ths writer is created, the given configuration instance
        /// cannot be passed to another writer. If you intend to do so, you should
        /// <seealso cref="IndexWriterConfig#clone() clone"/> it beforehand.
        /// </summary>
        /// <param name="d">
        ///          the index directory. The index is either created or appended
        ///          according <code>conf.getOpenMode()</code>. </param>
        /// <param name="conf">
        ///          the configuration settings according to which IndexWriter should
        ///          be initialized. </param>
        /// <exception cref="IOException">
        ///           if the directory cannot be read/written to, or if it does not
        ///           exist and <code>conf.getOpenMode()</code> is
        ///           <code>OpenMode.APPEND</code> or if there is any other low-level
        ///           IO error </exception>
        public IndexWriter(Directory d, IndexWriterConfig conf)
        {
            /*if (!InstanceFieldsInitialized)
            {
                InitializeInstanceFields();
                InstanceFieldsInitialized = true;
            }*/
            readerPool = new ReaderPool(this);
            conf.SetIndexWriter(this); // prevent reuse by other instances
            Config_Renamed = new LiveIndexWriterConfig(conf);
            directory = d;
            analyzer = Config_Renamed.Analyzer;
            infoStream = Config_Renamed.InfoStream;
            mergePolicy = Config_Renamed.MergePolicy;
            mergePolicy.IndexWriter = this;
            mergeScheduler = Config_Renamed.MergeScheduler;
            Codec = Config_Renamed.Codec;

            BufferedUpdatesStream = new BufferedUpdatesStream(infoStream);
            PoolReaders = Config_Renamed.ReaderPooling;

            WriteLock = directory.MakeLock(WRITE_LOCK_NAME);

            if (!WriteLock.Obtain(Config_Renamed.WriteLockTimeout)) // obtain write lock
            {
                throw new LockObtainFailedException("Index locked for write: " + WriteLock);
            }

            bool success = false;
            try
            {
                OpenMode_e? mode = Config_Renamed.OpenMode;
                bool create;
                if (mode == OpenMode_e.CREATE)
                {
                    create = true;
                }
                else if (mode == OpenMode_e.APPEND)
                {
                    create = false;
                }
                else
                {
                    // CREATE_OR_APPEND - create only if an index does not exist
                    create = !DirectoryReader.IndexExists(directory);
                }

                // If index is too old, reading the segments will throw
                // IndexFormatTooOldException.
                segmentInfos = new SegmentInfos();

                bool initialIndexExists = true;

                if (create)
                {
                    // Try to read first.  this is to allow create
                    // against an index that's currently open for
                    // searching.  In this case we write the next
                    // segments_N file with no segments:
                    try
                    {
                        segmentInfos.Read(directory);
                        segmentInfos.Clear();
                    }
                    catch (IOException)
                    {
                        // Likely this means it's a fresh directory
                        initialIndexExists = false;
                    }

                    // Record that we have a change (zero out all
                    // segments) pending:
                    Changed();
                }
                else
                {
                    segmentInfos.Read(directory);

                    IndexCommit commit = Config_Renamed.IndexCommit;
                    if (commit != null)
                    {
                        // Swap out all segments, but, keep metadata in
                        // SegmentInfos, like version & generation, to
                        // preserve write-once.  this is important if
                        // readers are open against the future commit
                        // points.
                        if (commit.Directory != directory)
                        {
                            throw new System.ArgumentException("IndexCommit's directory doesn't match my directory");
                        }
                        SegmentInfos oldInfos = new SegmentInfos();
                        oldInfos.Read(directory, commit.SegmentsFileName);
                        segmentInfos.Replace(oldInfos);
                        Changed();
                        if (infoStream.IsEnabled("IW"))
                        {
                            infoStream.Message("IW", "init: loaded commit \"" + commit.SegmentsFileName + "\"");
                        }
                    }
                }

                RollbackSegments = segmentInfos.CreateBackupSegmentInfos();

                // start with previous field numbers, but new FieldInfos
                GlobalFieldNumberMap = FieldNumberMap;
                Config_Renamed.FlushPolicy.Init(Config_Renamed);
                DocWriter = new DocumentsWriter(this, Config_Renamed, directory);
                eventQueue = DocWriter.EventQueue();

                // Default deleter (for backwards compatibility) is
                // KeepOnlyLastCommitDeleter:
                lock (this)
                {
                    Deleter = new IndexFileDeleter(directory, Config_Renamed.DelPolicy, segmentInfos, infoStream, this, initialIndexExists);
                }

                if (Deleter.StartingCommitDeleted)
                {
                    // Deletion policy deleted the "head" commit point.
                    // We have to mark ourself as changed so that if we
                    // are closed w/o any further changes we write a new
                    // segments_N file.
                    Changed();
                }

                if (infoStream.IsEnabled("IW"))
                {
                    infoStream.Message("IW", "init: create=" + create);
                    MessageState();
                }

                success = true;
            }
            finally
            {
                if (!success)
                {
                    if (infoStream.IsEnabled("IW"))
                    {
                        infoStream.Message("IW", "init: hit exception on init; releasing write lock");
                    }
                    WriteLock.Release();
                    IOUtils.CloseWhileHandlingException(WriteLock);
                    WriteLock = null;
                }
            }
        }
Beispiel #17
0
        private void RollbackInternal()
        {
            bool success = false;

            if (infoStream.IsEnabled("IW"))
            {
                infoStream.Message("IW", "rollback");
            }

            try
            {
                lock (this)
                {
                    FinishMerges(false);
                    StopMerges = true;
                }

                if (infoStream.IsEnabled("IW"))
                {
                    infoStream.Message("IW", "rollback: done finish merges");
                }

                // Must pre-close these two, in case they increment
                // changeCount so that we can then set it to false
                // before calling closeInternal
                mergePolicy.Dispose();
                mergeScheduler.Dispose();

                BufferedUpdatesStream.Clear();
                DocWriter.Dispose(); // mark it as closed first to prevent subsequent indexing actions/flushes
                DocWriter.Abort(this); // don't sync on IW here
                lock (this)
                {
                    if (PendingCommit != null)
                    {
                        PendingCommit.RollbackCommit(directory);
                        Deleter.DecRef(PendingCommit);
                        PendingCommit = null;
                        Monitor.PulseAll(this);
                    }

                    // Don't bother saving any changes in our segmentInfos
                    readerPool.DropAll(false);

                    // Keep the same segmentInfos instance but replace all
                    // of its SegmentInfo instances.  this is so the next
                    // attempt to commit using this instance of IndexWriter
                    // will always write to a new generation ("write
                    // once").
                    segmentInfos.RollbackSegmentInfos(RollbackSegments);
                    if (infoStream.IsEnabled("IW"))
                    {
                        infoStream.Message("IW", "rollback: infos=" + SegString(segmentInfos.Segments));
                    }

                    Debug.Assert(TestPoint("rollback before checkpoint"));

                    // Ask deleter to locate unreferenced files & remove
                    // them:
                    Deleter.Checkpoint(segmentInfos, false);
                    Deleter.Refresh();

                    LastCommitChangeCount = ChangeCount;

                    Deleter.Refresh();
                    Deleter.Dispose();

                    WriteLock.Release();
                    IOUtils.Close(WriteLock); // release write lock
                    WriteLock = null;

                    Debug.Assert(DocWriter.PerThreadPool.NumDeactivatedThreadStates() == DocWriter.PerThreadPool.MaxThreadStates, "" + DocWriter.PerThreadPool.NumDeactivatedThreadStates() + " " + DocWriter.PerThreadPool.MaxThreadStates);
                }

                success = true;
            }
            catch (System.OutOfMemoryException oom)
            {
                HandleOOM(oom, "rollbackInternal");
            }
            finally
            {
                if (!success)
                {
                    // Must not hold IW's lock while closing
                    // mergePolicy/Scheduler: this can lead to deadlock,
                    // e.g. TestIW.testThreadInterruptDeadlock
                    IOUtils.CloseWhileHandlingException(mergePolicy, mergeScheduler);
                }
                lock (this)
                {
                    if (!success)
                    {
                        // we tried to be nice about it: do the minimum

                        // don't leak a segments_N file if there is a pending commit
                        if (PendingCommit != null)
                        {
                            try
                            {
                                PendingCommit.RollbackCommit(directory);
                                Deleter.DecRef(PendingCommit);
                            }
                            catch (Exception)
                            {
                            }
                        }

                        // close all the closeables we can (but important is readerPool and writeLock to prevent leaks)
                        if (WriteLock != null)
                        {
                            WriteLock.Release();
                        }
                        IOUtils.CloseWhileHandlingException(readerPool, Deleter, WriteLock);
                        WriteLock = null;
                    }
                    closed = true;
                    Closing = false;
                }
            }
        }
Beispiel #18
0
 public Condition(Lock l)
 {
     _lock = l;
     _waitingList = new NativeArray<TaskHandle>();
 }
        public void TestLockIdiomUnlocksWhenExceptionsAreThrown()
        {
            object sync = new object();
            try
            {
                lock (sync)
                {
                    Log("In locked section");
                    throw new Exception("Purposefully thrown");
                }
            }
            catch (Exception)
            { }

            bool secondThreadAcquiredLock = false;
            Lock secondThreadDoneLock = new Lock();
            Condition secondThreadDone = new Condition(secondThreadDoneLock);
            Thread secondThread = new Thread(delegate()
            {
                secondThreadAcquiredLock = Monitor.TryEnter(sync);
            });
            secondThread.Start();
            secondThreadDone.Await();
            Assert("Finally block of lock idiom should have unlocked sync obj", secondThreadAcquiredLock);
        }
Beispiel #20
0
 private static bool TryAcquireContended(Lock lck, Object obj, int millisecondsTimeout)
 {
     int removeCookie = t_blockingObjects.Add(obj, ReasonForBlocking.OnCrst);
     try
     {
         return lck.TryAcquire(millisecondsTimeout);
     }
     finally
     {
         t_blockingObjects.Remove(removeCookie);
     }
 }
Beispiel #21
0
        /// <summary>
        /// Register initially (eagerly) loaded modules.
        /// </summary>
        internal ModuleList()
        {
            _loadedModuleMap = new ModuleMap(new ModuleInfo[0]);
            _moduleRegistrationCallbacks = default(Action<ModuleInfo>);
            _moduleRegistrationLock = new Lock();

            // 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);

            foreach (IntPtr moduleHandle in loadedModuleHandles)
            {
                RegisterModule(moduleHandle);
            }
        }
Beispiel #22
0
        /// <summary>
        /// Register initially (eagerly) loaded modules.
        /// </summary>
        internal ModuleList()
        {
            _loadedModuleMap = new ModuleMap(new ModuleInfo[0]);
            _moduleRegistrationCallbacks = default(Action<ModuleInfo>);
            _moduleRegistrationLock = new Lock();

            RegisterNewModules(ModuleType.Eager);

            IntPtr systemObjectModule = RuntimeAugments.GetModuleFromTypeHandle(RuntimeAugments.RuntimeTypeHandleOf<object>());
            foreach (ModuleInfo m in _loadedModuleMap.Modules)
            {
                if (m.Handle == systemObjectModule)
                {
                    _systemModule = m;
                    break;
                }
            }
        }
Beispiel #23
0
        private void CloseInternal(bool waitForMerges, bool doFlush)
        {
            bool interrupted = false;
            try
            {
                if (PendingCommit != null)
                {
                    throw new InvalidOperationException("cannot close: prepareCommit was already called with no corresponding call to commit");
                }

                if (infoStream.IsEnabled("IW"))
                {
                    infoStream.Message("IW", "now flush at close waitForMerges=" + waitForMerges);
                }

                DocWriter.Dispose();

                try
                {
                    // Only allow a new merge to be triggered if we are
                    // going to wait for merges:
                    if (doFlush)
                    {
                        Flush(waitForMerges, true);
                    }
                    else
                    {
                        DocWriter.Abort(this); // already closed -- never sync on IW
                    }
                }
                finally
                {
                    try
                    {
                        // clean up merge scheduler in all cases, although flushing may have failed:
                        //interrupted = Thread.Interrupted();
                        //LUCENE TO-DO
                        interrupted = false;

                        if (waitForMerges)
                        {
                            try
                            {
                                // Give merge scheduler last chance to run, in case
                                // any pending merges are waiting:
                                mergeScheduler.Merge(this, MergeTrigger.CLOSING, false);
                            }
                            catch (ThreadInterruptedException)
                            {
                                // ignore any interruption, does not matter
                                interrupted = true;
                                if (infoStream.IsEnabled("IW"))
                                {
                                    infoStream.Message("IW", "interrupted while waiting for final merges");
                                }
                            }
                        }

                        lock (this)
                        {
                            for (; ; )
                            {
                                try
                                {
                                    FinishMerges(waitForMerges && !interrupted);
                                    break;
                                }
                                catch (ThreadInterruptedException)
                                {
                                    // by setting the interrupted status, the
                                    // next call to finishMerges will pass false,
                                    // so it will not wait
                                    interrupted = true;
                                    if (infoStream.IsEnabled("IW"))
                                    {
                                        infoStream.Message("IW", "interrupted while waiting for merges to finish");
                                    }
                                }
                            }
                            StopMerges = true;
                        }
                    }
                    finally
                    {
                        // shutdown policy, scheduler and all threads (this call is not interruptible):
                        IOUtils.CloseWhileHandlingException(mergePolicy, mergeScheduler);
                    }
                }

                if (infoStream.IsEnabled("IW"))
                {
                    infoStream.Message("IW", "now call final commit()");
                }

                if (doFlush)
                {
                    CommitInternal();
                }
                ProcessEvents(false, true);
                lock (this)
                {
                    // commitInternal calls ReaderPool.commit, which
                    // writes any pending liveDocs from ReaderPool, so
                    // it's safe to drop all readers now:
                    readerPool.DropAll(true);
                    Deleter.Dispose();
                }

                if (infoStream.IsEnabled("IW"))
                {
                    infoStream.Message("IW", "at close: " + SegString());
                }

                if (WriteLock != null)
                {
                    WriteLock.Release(); // release write lock
                    WriteLock.Dispose();
                    WriteLock = null;
                }
                lock (this)
                {
                    closed = true;
                }
                Debug.Assert(DocWriter.PerThreadPool.NumDeactivatedThreadStates() == DocWriter.PerThreadPool.MaxThreadStates, "" + DocWriter.PerThreadPool.NumDeactivatedThreadStates() + " " + DocWriter.PerThreadPool.MaxThreadStates);
            }
            catch (System.OutOfMemoryException oom)
            {
                HandleOOM(oom, "closeInternal");
            }
            finally
            {
                lock (this)
                {
                    Closing = false;
                    Monitor.PulseAll(this);
                    if (!closed)
                    {
                        if (infoStream.IsEnabled("IW"))
                        {
                            infoStream.Message("IW", "hit exception while closing");
                        }
                    }
                }
                // finally, restore interrupt status:
                if (interrupted)
                {
                    Thread.CurrentThread.Interrupt();
                }
            }
        }
Beispiel #24
0
        /// <summary>
        /// Assigns a sync table entry to the object in a thread-safe way.
        /// </summary>
        public static unsafe int AssignEntry(object obj, int* pHeader)
        {
            // Allocate the synchronization object outside the lock
            Lock lck = new Lock();

            using (LockHolder.Hold(s_freeEntriesLock))
            {
                // After acquiring the lock check whether another thread already assigned the sync entry
                int hashOrIndex;
                if (ObjectHeader.GetSyncEntryIndex(*pHeader, out hashOrIndex))
                {
                    return hashOrIndex;
                }

                // Allocate a new sync entry.  First, make sure all data is ready.  This call may OOM.
                GCHandle owner = GCHandle.Alloc(obj, GCHandleType.WeakTrackResurrection);

                try
                {
                    // Now find a free entry in the table
                    int syncIndex;

                    if (s_freeEntryList != 0)
                    {
                        // Grab a free entry from the list
                        syncIndex = s_freeEntryList;
                        s_freeEntryList = s_entries[syncIndex].Next;
                        s_entries[syncIndex].Next = 0;
                    }
                    else if (s_unusedEntryIndex < s_entries.Length)
                    {
                        // Grab the next unused entry
                        syncIndex = s_unusedEntryIndex++;
                    }
                    else
                    {
                        // No free entries, use the slow path.  This call may OOM.
                        syncIndex = EnsureFreeEntry();
                    }

                    // Found a free entry to assign
                    Debug.Assert(!s_entries[syncIndex].Owner.IsAllocated);
                    Debug.Assert(s_entries[syncIndex].Lock == null);
                    Debug.Assert(s_entries[syncIndex].HashCode == 0);

                    // Set up the new entry.  We should not fail after this point.
                    s_entries[syncIndex].Lock = lck;
                    // The hash code will be set by the SetSyncEntryIndex call below
                    s_entries[syncIndex].Owner = owner;
                    owner = default(GCHandle);

                    // Finally, store the entry index in the object header
                    ObjectHeader.SetSyncEntryIndex(pHeader, syncIndex);
                    return syncIndex;
                }
                finally
                {
                    if (owner.IsAllocated)
                    {
                        owner.Free();
                    }
                }
            }
        }
Beispiel #25
0
        private static XmlHttpRequest _doSimpleXmlHttpRequest(string url, RequestMethod method, string postData, string username, string password, int timeoutMs)
        {
            XmlHttpRequest xhr = GetXmlHttpRequest();
            Lock l = new Lock();
            l.Acquire();
            Condition condition = new Condition(l);
            if (_driverProcess == null)
            {
                throw new SystemException("XmlHttpRequestManager.Driver was not started.");
            }
            OnReadyStateChangeSignalHandler handler = new OnReadyStateChangeSignalHandler
            {
                XmlHttpRequest = xhr,
                Condition = condition
            };

            // TODO: Use resource manager to ensure these signal senders and handlers get cleaned up
            OnReadyStateChangeSignalSender signalSender = CreateOnReadyStateChangeSignalSender(handler);
            try
            {
                xhr.OnReadyStateChange = (NativeFunction)new NativeVoidDelegate(signalSender.SendSignal);
                string methodString;
                if (method == RequestMethod.Get)
                {
                    methodString = "GET";
                }
                else
                {
                    methodString = "POST";
                }
                xhr.Open(methodString, url, true, username, password);
                xhr.Send(postData);
                if (timeoutMs > 0)
                {
                    if (!condition.Await(timeoutMs))
                    {
                        xhr.OnReadyStateChange = null;
                        throw new XmlHttpRequestTimeoutException("Timed out waiting for " + url, xhr);
                    }
                }
                else
                {
                    condition.Await();
                }
                // TODO: finally blocks are not executed if there is a return statement in the try block.  fix that
            }
            finally
            {
                DestroyOnReadyStateChangeSignalSender(signalSender);
            }
            return xhr;
        }