http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net.Tests/Support/TestThreadClass.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Tests/Support/TestThreadClass.cs b/src/Lucene.Net.Tests/Support/TestThreadClass.cs deleted file mode 100644 index 82bb430..0000000 --- a/src/Lucene.Net.Tests/Support/TestThreadClass.cs +++ /dev/null @@ -1,60 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * -*/ - -using Lucene.Net.Attributes; -using NUnit.Framework; - -namespace Lucene.Net.Support -{ - [TestFixture] - public class TestThreadClass - { - [Test, LuceneNetSpecific] - public void Test() - { - ThreadClass thread = new ThreadClass(); - - //Compare Current Thread Ids - Assert.IsTrue(ThreadClass.Current().Instance.ManagedThreadId == System.Threading.Thread.CurrentThread.ManagedThreadId); - - - //Compare instances of ThreadClass - MyThread mythread = new MyThread(); - mythread.Start(); - while (mythread.Result == null) System.Threading.Thread.Sleep(1); - Assert.IsTrue((bool)mythread.Result); - - - ThreadClass nullThread = null; - Assert.IsTrue(nullThread == null); //test overloaded operator == with null values - Assert.IsFalse(nullThread != null); //test overloaded operator != with null values - } - - class MyThread : ThreadClass - { - public object Result = null; - public override void Run() - { - Result = ThreadClass.Current() == this; - } - } - } -}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net.Tests/Support/Threading/TestCloseableThreadLocal.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Tests/Support/Threading/TestCloseableThreadLocal.cs b/src/Lucene.Net.Tests/Support/Threading/TestCloseableThreadLocal.cs new file mode 100644 index 0000000..8c509df --- /dev/null +++ b/src/Lucene.Net.Tests/Support/Threading/TestCloseableThreadLocal.cs @@ -0,0 +1,113 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +using Lucene.Net.Analysis; +using Lucene.Net.Attributes; +using Lucene.Net.Documents; +using Lucene.Net.Index; +using Lucene.Net.Search; +using Lucene.Net.Store; +using NUnit.Framework; +using System; +using Version = Lucene.Net.Util.LuceneVersion; + +#pragma warning disable 612, 618 +namespace Lucene.Net.Support.Threading +{ + [TestFixture] + public class TestCloseableThreadLocal + { + [Test, LuceneNetSpecific] + public void TestMemLeakage() + { + DisposableThreadLocalProfiler.EnableIDisposableThreadLocalProfiler = true; + + int LoopCount = 100; + Analyzer[] analyzers = new Analyzer[LoopCount]; + RAMDirectory[] dirs = new RAMDirectory[LoopCount]; + IndexWriter[] indexWriters = new IndexWriter[LoopCount]; + + System.Threading.Tasks.Parallel.For(0, LoopCount, (i) => + { + analyzers[i] = new Lucene.Net.Analysis.Standard.StandardAnalyzer(Version.LUCENE_CURRENT); + dirs[i] = new RAMDirectory(); + var conf = new IndexWriterConfig(Version.LUCENE_CURRENT, analyzers[i]); + indexWriters[i] = new IndexWriter(dirs[i], conf /*analyzers[i], true, IndexWriter.MaxFieldLength.UNLIMITED*/); + }); + + System.Threading.Tasks.Parallel.For(0, LoopCount, (i) => + { + Document document = new Document(); + document.Add(new Field("field", "some test", Field.Store.NO, Field.Index.ANALYZED)); + indexWriters[i].AddDocument(document); + }); + + System.Threading.Tasks.Parallel.For(0, LoopCount, (i) => + { + analyzers[i].Dispose(); + indexWriters[i].Dispose(); + }); + + System.Threading.Tasks.Parallel.For(0, LoopCount, (i) => + { + using (IndexReader reader = DirectoryReader.Open(dirs[i])) + { + IndexSearcher searcher = new IndexSearcher(reader); + TopDocs d = searcher.Search(new TermQuery(new Term("field", "test")), 10); + } + }); + + System.Threading.Tasks.Parallel.For(0, LoopCount, (i) => dirs[i].Dispose()); + + GC.Collect(GC.MaxGeneration); + GC.WaitForPendingFinalizers(); + + int aliveObjects = 0; + foreach (WeakReference w in DisposableThreadLocalProfiler.Instances) + { + object o = w.Target; + if (o != null) aliveObjects++; + } + + DisposableThreadLocalProfiler.EnableIDisposableThreadLocalProfiler = false; + + Assert.AreEqual(0, aliveObjects); + } + } +} + +#if NET35 + +namespace System.Threading.Tasks +{ + public static class Parallel + { + public static void For(int start, int end, Action<int> loopAction) + { + for(int i = start; i < end; i++) + { + loopAction(i); + } + } + } +} +#pragma warning restore 612, 618 +#endif \ No newline at end of file http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net.Tests/Support/Threading/TestThreadClass.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Tests/Support/Threading/TestThreadClass.cs b/src/Lucene.Net.Tests/Support/Threading/TestThreadClass.cs new file mode 100644 index 0000000..5c1e8f0 --- /dev/null +++ b/src/Lucene.Net.Tests/Support/Threading/TestThreadClass.cs @@ -0,0 +1,60 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +using Lucene.Net.Attributes; +using NUnit.Framework; + +namespace Lucene.Net.Support.Threading +{ + [TestFixture] + public class TestThreadClass + { + [Test, LuceneNetSpecific] + public void Test() + { + ThreadClass thread = new ThreadClass(); + + //Compare Current Thread Ids + Assert.IsTrue(ThreadClass.Current().Instance.ManagedThreadId == System.Threading.Thread.CurrentThread.ManagedThreadId); + + + //Compare instances of ThreadClass + MyThread mythread = new MyThread(); + mythread.Start(); + while (mythread.Result == null) System.Threading.Thread.Sleep(1); + Assert.IsTrue((bool)mythread.Result); + + + ThreadClass nullThread = null; + Assert.IsTrue(nullThread == null); //test overloaded operator == with null values + Assert.IsFalse(nullThread != null); //test overloaded operator != with null values + } + + class MyThread : ThreadClass + { + public object Result = null; + public override void Run() + { + Result = ThreadClass.Current() == this; + } + } + } +} http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net.Tests/TestWorstCaseTestBehavior.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Tests/TestWorstCaseTestBehavior.cs b/src/Lucene.Net.Tests/TestWorstCaseTestBehavior.cs index fbbe4d6..801449d 100644 --- a/src/Lucene.Net.Tests/TestWorstCaseTestBehavior.cs +++ b/src/Lucene.Net.Tests/TestWorstCaseTestBehavior.cs @@ -1,4 +1,4 @@ -using Lucene.Net.Support; +using Lucene.Net.Support.Threading; using Lucene.Net.Util; using NUnit.Framework; using System; http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net.Tests/Util/TestDoubleBarrelLRUCache.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Tests/Util/TestDoubleBarrelLRUCache.cs b/src/Lucene.Net.Tests/Util/TestDoubleBarrelLRUCache.cs index 5a05124..5064ea4 100644 --- a/src/Lucene.Net.Tests/Util/TestDoubleBarrelLRUCache.cs +++ b/src/Lucene.Net.Tests/Util/TestDoubleBarrelLRUCache.cs @@ -1,4 +1,4 @@ -using Lucene.Net.Support; +using Lucene.Net.Support.Threading; using NUnit.Framework; using System; http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net.Tests/Util/TestSetOnce.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Tests/Util/TestSetOnce.cs b/src/Lucene.Net.Tests/Util/TestSetOnce.cs index 5e03a29..22deb08 100644 --- a/src/Lucene.Net.Tests/Util/TestSetOnce.cs +++ b/src/Lucene.Net.Tests/Util/TestSetOnce.cs @@ -1,4 +1,4 @@ -using Lucene.Net.Support; +using Lucene.Net.Support.Threading; using NUnit.Framework; using System; using System.Globalization; http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net.Tests/Util/TestWeakIdentityMap.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Tests/Util/TestWeakIdentityMap.cs b/src/Lucene.Net.Tests/Util/TestWeakIdentityMap.cs index 48270e0..9c0286a 100644 --- a/src/Lucene.Net.Tests/Util/TestWeakIdentityMap.cs +++ b/src/Lucene.Net.Tests/Util/TestWeakIdentityMap.cs @@ -1,6 +1,7 @@ using Lucene.Net.Attributes; using Lucene.Net.Randomized.Generators; using Lucene.Net.Support; +using Lucene.Net.Support.Threading; using NUnit.Framework; using System; using System.Collections.Concurrent; http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net/Index/ConcurrentMergeScheduler.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net/Index/ConcurrentMergeScheduler.cs b/src/Lucene.Net/Index/ConcurrentMergeScheduler.cs index 231160b..04467f4 100644 --- a/src/Lucene.Net/Index/ConcurrentMergeScheduler.cs +++ b/src/Lucene.Net/Index/ConcurrentMergeScheduler.cs @@ -1,5 +1,5 @@ #if FEATURE_CONCURRENTMERGESCHEDULER -using Lucene.Net.Support; +using Lucene.Net.Support.Threading; using System; using System.Collections.Generic; using System.Text; http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net/Index/DocumentsWriterDeleteQueue.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net/Index/DocumentsWriterDeleteQueue.cs b/src/Lucene.Net/Index/DocumentsWriterDeleteQueue.cs index 640d6b9..36052ef 100644 --- a/src/Lucene.Net/Index/DocumentsWriterDeleteQueue.cs +++ b/src/Lucene.Net/Index/DocumentsWriterDeleteQueue.cs @@ -1,4 +1,5 @@ using Lucene.Net.Support; +using Lucene.Net.Support.Threading; using System; using System.Diagnostics; using System.Threading; http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net/Index/DocumentsWriterFlushQueue.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net/Index/DocumentsWriterFlushQueue.cs b/src/Lucene.Net/Index/DocumentsWriterFlushQueue.cs index 72b4e7d..9ef285a 100644 --- a/src/Lucene.Net/Index/DocumentsWriterFlushQueue.cs +++ b/src/Lucene.Net/Index/DocumentsWriterFlushQueue.cs @@ -1,4 +1,5 @@ using Lucene.Net.Support; +using Lucene.Net.Support.Threading; using System; using System.Collections.Generic; using System.Diagnostics; http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net/Index/DocumentsWriterPerThreadPool.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net/Index/DocumentsWriterPerThreadPool.cs b/src/Lucene.Net/Index/DocumentsWriterPerThreadPool.cs index 2dc84c1..4c2dc81 100644 --- a/src/Lucene.Net/Index/DocumentsWriterPerThreadPool.cs +++ b/src/Lucene.Net/Index/DocumentsWriterPerThreadPool.cs @@ -1,3 +1,4 @@ +using Lucene.Net.Support.Threading; using System; using System.Diagnostics; using System.Threading; @@ -21,8 +22,6 @@ namespace Lucene.Net.Index * limitations under the License. */ - using Lucene.Net.Support; - /// <summary> /// <see cref="DocumentsWriterPerThreadPool"/> controls <see cref="ThreadState"/> instances /// and their thread assignments during indexing. Each <see cref="ThreadState"/> holds http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net/Index/DocumentsWriterStallControl.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net/Index/DocumentsWriterStallControl.cs b/src/Lucene.Net/Index/DocumentsWriterStallControl.cs index 1b5c322..7dd1581 100644 --- a/src/Lucene.Net/Index/DocumentsWriterStallControl.cs +++ b/src/Lucene.Net/Index/DocumentsWriterStallControl.cs @@ -1,4 +1,5 @@ using Lucene.Net.Support; +using Lucene.Net.Support.Threading; using System; using System.Collections.Generic; using System.Diagnostics; http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net/Index/TaskMergeScheduler.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net/Index/TaskMergeScheduler.cs b/src/Lucene.Net/Index/TaskMergeScheduler.cs index cac1a34..d87c4dc 100644 --- a/src/Lucene.Net/Index/TaskMergeScheduler.cs +++ b/src/Lucene.Net/Index/TaskMergeScheduler.cs @@ -1,4 +1,4 @@ -using Lucene.Net.Support; +using Lucene.Net.Support.Threading; using Lucene.Net.Util; using System; using System.Collections.Generic; http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net/Lucene.Net.csproj ---------------------------------------------------------------------- diff --git a/src/Lucene.Net/Lucene.Net.csproj b/src/Lucene.Net/Lucene.Net.csproj index 16e9d51..bfb8433 100644 --- a/src/Lucene.Net/Lucene.Net.csproj +++ b/src/Lucene.Net/Lucene.Net.csproj @@ -652,7 +652,7 @@ <Compile Include="Support\IO\FileStreamExtensions.cs" /> <Compile Include="Support\ICallable.cs" /> <Compile Include="Support\ICharSequence.cs" /> - <Compile Include="Support\ICompletionService.cs" /> + <Compile Include="Support\Threading\ICompletionService.cs" /> <Compile Include="Support\IO\IDataInput.cs" /> <Compile Include="Support\IO\IDataOutput.cs" /> <Compile Include="Support\IdentityComparer.cs" /> @@ -675,7 +675,7 @@ <Compile Include="Support\IO\ReadWriteHeapByteBuffer.cs" /> <Compile Include="Support\IO\ReadWriteLongArrayBuffer.cs" /> <Compile Include="Support\IResourceManagerFactory.cs" /> - <Compile Include="Support\LimitedConcurrencyLevelTaskScheduler.cs" /> + <Compile Include="Support\Threading\LimitedConcurrencyLevelTaskScheduler.cs" /> <Compile Include="Support\LinkedHashMap.cs" /> <Compile Include="Support\ListExtensions.cs" /> <Compile Include="Support\LurchTable.cs" /> @@ -683,8 +683,8 @@ <Compile Include="Support\IO\MemoryMappedFileByteBuffer.cs" /> <Compile Include="Support\NumberFormat.cs" /> <Compile Include="Support\PriorityQueue.cs" /> - <Compile Include="Support\ReaderWriterLockSlimExtensions.cs" /> - <Compile Include="Support\ReentrantLock.cs" /> + <Compile Include="Support\Threading\ReaderWriterLockSlimExtensions.cs" /> + <Compile Include="Support\Threading\ReentrantLock.cs" /> <Compile Include="Support\IO\SafeTextWriterWrapper.cs" /> <Compile Include="Support\SetExtensions.cs" /> <Compile Include="Support\SignedZeroComparer.cs" /> @@ -693,18 +693,18 @@ <Compile Include="Support\StringCharSequenceWrapper.cs" /> <Compile Include="Support\StringExtensions.cs" /> <Compile Include="Support\StringTokenizer.cs" /> - <Compile Include="Support\TaskSchedulerCompletionService.cs" /> - <Compile Include="Support\ThreadFactory.cs" /> + <Compile Include="Support\Threading\TaskSchedulerCompletionService.cs" /> + <Compile Include="Support\Threading\ThreadFactory.cs" /> <Compile Include="Support\Time.cs" /> <Compile Include="Support\TreeDictionary.cs" /> <Compile Include="Support\TreeSet.cs" /> - <Compile Include="Support\CloseableThreadLocalProfiler.cs" /> + <Compile Include="Support\Threading\CloseableThreadLocalProfiler.cs" /> <Compile Include="Support\Compatibility\ConcurrentDictionary.cs" /> <Compile Include="Support\Compatibility\Func.cs" /> <Compile Include="Support\Compatibility\ISet.cs" /> <Compile Include="Support\Compatibility\SetFactory.cs" /> <Compile Include="Support\Compatibility\SortedSet.cs" /> - <Compile Include="Support\Compatibility\ThreadLocal.cs" /> + <Compile Include="Support\Threading\ThreadLocal.cs" /> <Compile Include="Support\Compatibility\WrappedHashSet.cs" /> <Compile Include="Support\CRC32.cs" /> <Compile Include="Support\IO\Compression\Deflater.cs" /> @@ -714,12 +714,12 @@ <Compile Include="Support\HashMap.cs" /> <Compile Include="Support\IChecksum.cs" /> <Compile Include="Support\IO\Compression\Inflater.cs" /> - <Compile Include="Support\IThreadRunnable.cs" /> + <Compile Include="Support\Threading\IThreadRunnable.cs" /> <Compile Include="Support\Number.cs" /> <Compile Include="Support\OS.cs" /> <Compile Include="Support\IO\Compression\SharpZipLib.cs" /> - <Compile Include="Support\ThreadClass.cs" /> - <Compile Include="Support\ThreadLock.cs" /> + <Compile Include="Support\Threading\ThreadClass.cs" /> + <Compile Include="Support\Threading\ThreadLock.cs" /> <Compile Include="Support\Util\ExcludeServiceAttribute.cs" /> <Compile Include="Support\Util\IServiceListable.cs" /> <Compile Include="Support\Util\NamedServiceFactory.cs" /> http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net/Search/ControlledRealTimeReopenThread.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net/Search/ControlledRealTimeReopenThread.cs b/src/Lucene.Net/Search/ControlledRealTimeReopenThread.cs index 34f4f9a..73a361b 100644 --- a/src/Lucene.Net/Search/ControlledRealTimeReopenThread.cs +++ b/src/Lucene.Net/Search/ControlledRealTimeReopenThread.cs @@ -1,4 +1,5 @@ using Lucene.Net.Support; +using Lucene.Net.Support.Threading; using System; using System.Threading; http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net/Search/IndexSearcher.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net/Search/IndexSearcher.cs b/src/Lucene.Net/Search/IndexSearcher.cs index ae3e4f4..89bf357 100644 --- a/src/Lucene.Net/Search/IndexSearcher.cs +++ b/src/Lucene.Net/Search/IndexSearcher.cs @@ -1,4 +1,5 @@ using Lucene.Net.Support; +using Lucene.Net.Support.Threading; using System; using System.Collections; using System.Collections.Generic; http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net/Search/ReferenceManager.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net/Search/ReferenceManager.cs b/src/Lucene.Net/Search/ReferenceManager.cs index a4d7df8..6f4e2f8 100644 --- a/src/Lucene.Net/Search/ReferenceManager.cs +++ b/src/Lucene.Net/Search/ReferenceManager.cs @@ -1,4 +1,5 @@ using Lucene.Net.Support; +using Lucene.Net.Support.Threading; using System; using System.Collections.Generic; using System.Diagnostics; http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net/Search/TimeLimitingCollector.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net/Search/TimeLimitingCollector.cs b/src/Lucene.Net/Search/TimeLimitingCollector.cs index b16aa36..2bb2689 100644 --- a/src/Lucene.Net/Search/TimeLimitingCollector.cs +++ b/src/Lucene.Net/Search/TimeLimitingCollector.cs @@ -1,4 +1,4 @@ -using Lucene.Net.Support; +using Lucene.Net.Support.Threading; using System; #if FEATURE_SERIALIZABLE using System.Runtime.Serialization; http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net/Store/LockVerifyServer.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net/Store/LockVerifyServer.cs b/src/Lucene.Net/Store/LockVerifyServer.cs index 3a376c4..f65d243 100644 --- a/src/Lucene.Net/Store/LockVerifyServer.cs +++ b/src/Lucene.Net/Store/LockVerifyServer.cs @@ -1,4 +1,4 @@ -using Lucene.Net.Support; +using Lucene.Net.Support.Threading; using System; using System.IO; using System.Net; http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net/Support/CloseableThreadLocalProfiler.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net/Support/CloseableThreadLocalProfiler.cs b/src/Lucene.Net/Support/CloseableThreadLocalProfiler.cs deleted file mode 100644 index c90cc52..0000000 --- a/src/Lucene.Net/Support/CloseableThreadLocalProfiler.cs +++ /dev/null @@ -1,45 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * -*/ - -using System; - -namespace Lucene.Net.Support -{ - /// <summary> - /// For Debuging purposes. - /// </summary> - public class DisposableThreadLocalProfiler - { - private static bool _enableIDisposableThreadLocalProfiler = false; - public static System.Collections.Generic.List<WeakReference> Instances = new System.Collections.Generic.List<WeakReference>(); - - public static bool EnableIDisposableThreadLocalProfiler - { - get { return _enableIDisposableThreadLocalProfiler; } - set - { - _enableIDisposableThreadLocalProfiler = value; - lock (Instances) - Instances.Clear(); - } - } - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net/Support/Compatibility/ThreadLocal.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net/Support/Compatibility/ThreadLocal.cs b/src/Lucene.Net/Support/Compatibility/ThreadLocal.cs deleted file mode 100644 index 35bb26a..0000000 --- a/src/Lucene.Net/Support/Compatibility/ThreadLocal.cs +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if NET35 - -using System; - -namespace Lucene.Net.Support.Compatibility -{ - public class ThreadLocal<T> : IDisposable - { - [ThreadStatic] - static WeakDictionary<ThreadLocal<T>, T> slots; - - static void Init() - { - if (slots == null) slots = new WeakDictionary<ThreadLocal<T>, T>(); - } - - public T Value - { - set - { - Init(); - slots.Add(this, value); - } - get - { - Init(); - return (T)slots[this]; - } - } - - public void Dispose() - { - if (slots != null) slots.Remove(this); - } - } -} - -#endif \ No newline at end of file http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net/Support/ICompletionService.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net/Support/ICompletionService.cs b/src/Lucene.Net/Support/ICompletionService.cs deleted file mode 100644 index 69d862f..0000000 --- a/src/Lucene.Net/Support/ICompletionService.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Threading.Tasks; - -namespace Lucene.Net.Support -{ - /* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - public interface ICompletionService<V> - { - //Task<V> Poll(); - - //Task<V> Poll(long timeout, TimeUnit unit); - - Task<V> Submit(ICallable<V> task); - - Task<V> Take(); - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net/Support/IThreadRunnable.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net/Support/IThreadRunnable.cs b/src/Lucene.Net/Support/IThreadRunnable.cs deleted file mode 100644 index de8017a..0000000 --- a/src/Lucene.Net/Support/IThreadRunnable.cs +++ /dev/null @@ -1,36 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * -*/ - -namespace Lucene.Net.Support -{ - /// <summary> - /// this interface should be implemented by any class whose instances are intended - /// to be executed by a thread. - /// </summary> - public interface IThreadRunnable - { - /// <summary> - /// this method has to be implemented in order that starting of the thread causes the object's - /// run method to be called in that separately executing thread. - /// </summary> - void Run(); - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net/Support/LimitedConcurrencyLevelTaskScheduler.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net/Support/LimitedConcurrencyLevelTaskScheduler.cs b/src/Lucene.Net/Support/LimitedConcurrencyLevelTaskScheduler.cs deleted file mode 100644 index 37b617f..0000000 --- a/src/Lucene.Net/Support/LimitedConcurrencyLevelTaskScheduler.cs +++ /dev/null @@ -1,187 +0,0 @@ -/* -MICROSOFT LIMITED PUBLIC LICENSE version 1.1 -This license governs use of code marked as "sample" or "example" available on this web site -without a license agreement, as provided under the section above titled -"NOTICE SPECIFIC TO SOFTWARE AVAILABLE ON THIS WEB SITE." If you use such -code (the "software"), you accept this license. If you do not accept the -license, do not use the software. - -1. Definitions -The terms "reproduce," "reproduction," "derivative works," and "distribution" have the -same meaning here as under U.S. copyright law. -A "contribution" is the original software, or any additions or changes to the software. -A "contributor" is any person that distributes its contribution under this license. -"Licensed patents" are a contributorâs patent claims that read directly on its contribution. - -2. Grant of Rights -(A) Copyright Grant - Subject to the terms of this license, including the license conditions -and limitations in section 3, each contributor grants you a non-exclusive, worldwide, -royalty-free copyright license to reproduce its contribution, prepare derivative works -of its contribution, and distribute its contribution or any derivative works that you create. -(B) Patent Grant - Subject to the terms of this license, including the license conditions -and limitations in section 3, each contributor grants you a non-exclusive, worldwide, -royalty-free license under its licensed patents to make, have made, use, sell, -offer for sale, import, and/or otherwise dispose of its contribution in the -software or derivative works of the contribution in the software. - -3. Conditions and Limitations -(A) No Trademark License- This license does not grant you rights to use any contributorsâ -name, logo, or trademarks. -(B) If you bring a patent claim against any contributor over patents that you claim are -infringed by the software, your patent license from such contributor to the software -ends automatically. -(C) If you distribute any portion of the software, you must retain all copyright, patent, -trademark, and attribution notices that are present in the software. -(D) If you distribute any portion of the software in source code form, you may do so only -under this license by including a complete copy of this license with your distribution. -If you distribute any portion of the software in compiled or object code form, you may -only do so under a license that complies with this license. -(E) The software is licensed "as-is." You bear the risk of using it. The contributors -give no express warranties, guarantees or conditions. You may have additional consumer -rights under your local laws which this license cannot change. To the extent permitted -under your local laws, the contributors exclude the implied warranties of merchantability, -fitness for a particular purpose and non-infringement. -(F) Platform Limitation - The licenses granted in sections 2(A) and 2(B) extend only -to the software or derivative works that you create that run directly on a Microsoft -Windows operating system product, Microsoft run-time technology (such as the .NET -Framework or Silverlight), or Microsoft application platform (such as Microsoft -Office or Microsoft Dynamics). -*/ - -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace Lucene.Net.Support -{ - /// <summary> - /// Provides a task scheduler that ensures a maximum concurrency level while - /// running on top of the thread pool. - /// - /// Source: https://msdn.microsoft.com/en-us/library/system.threading.tasks.taskscheduler(v=vs.110).aspx - /// </summary> - public class LimitedConcurrencyLevelTaskScheduler : TaskScheduler - { - // Indicates whether the current thread is processing work items. - [ThreadStatic] - private static bool _currentThreadIsProcessingItems; - - // The list of tasks to be executed - private readonly LinkedList<Task> _tasks = new LinkedList<Task>(); // protected by lock(_tasks) - - // The maximum concurrency level allowed by this scheduler. - private readonly int _maxDegreeOfParallelism; - - // Indicates whether the scheduler is currently processing work items. - private int _delegatesQueuedOrRunning = 0; - - // Creates a new instance with the specified degree of parallelism. - public LimitedConcurrencyLevelTaskScheduler(int maxDegreeOfParallelism) - { - if (maxDegreeOfParallelism < 1) throw new ArgumentOutOfRangeException("maxDegreeOfParallelism"); - _maxDegreeOfParallelism = maxDegreeOfParallelism; - } - - // Queues a task to the scheduler. - protected sealed override void QueueTask(Task task) - { - // Add the task to the list of tasks to be processed. If there aren't enough - // delegates currently queued or running to process tasks, schedule another. - lock (_tasks) - { - _tasks.AddLast(task); - if (_delegatesQueuedOrRunning < _maxDegreeOfParallelism) - { - ++_delegatesQueuedOrRunning; - NotifyThreadPoolOfPendingWork(); - } - } - } - - // Inform the ThreadPool that there's work to be executed for this scheduler. - private void NotifyThreadPoolOfPendingWork() - { -#if FEATURE_THREADPOOL_UNSAFEQUEUEWORKITEM - ThreadPool.UnsafeQueueUserWorkItem( -#else - ThreadPool.QueueUserWorkItem( -#endif - _ => - { - // Note that the current thread is now processing work items. - // This is necessary to enable inlining of tasks into this thread. - _currentThreadIsProcessingItems = true; - try - { - // Process all available items in the queue. - while (true) - { - Task item; - lock (_tasks) - { - // When there are no more items to be processed, - // note that we're done processing, and get out. - if (_tasks.Count == 0) - { - --_delegatesQueuedOrRunning; - break; - } - - // Get the next item from the queue - item = _tasks.First.Value; - _tasks.Remove(item); - } - - // Execute the task we pulled out of the queue - base.TryExecuteTask(item); - } - } - // We're done processing items on the current thread - finally { _currentThreadIsProcessingItems = false; } - }, null); - } - - // Attempts to execute the specified task on the current thread. - protected sealed override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued) - { - // If this thread isn't already processing a task, we don't support inlining - if (!_currentThreadIsProcessingItems) return false; - - // If the task was previously queued, remove it from the queue - if (taskWasPreviouslyQueued) - // Try to run the task. - if (TryDequeue(task)) - return base.TryExecuteTask(task); - else - return false; - else - return base.TryExecuteTask(task); - } - - // Attempt to remove a previously scheduled task from the scheduler. - protected sealed override bool TryDequeue(Task task) - { - lock (_tasks) return _tasks.Remove(task); - } - - // Gets the maximum concurrency level supported by this scheduler. - public sealed override int MaximumConcurrencyLevel { get { return _maxDegreeOfParallelism; } } - - // Gets an enumerable of the tasks currently scheduled on this scheduler. - protected sealed override IEnumerable<Task> GetScheduledTasks() - { - bool lockTaken = false; - try - { - Monitor.TryEnter(_tasks, ref lockTaken); - if (lockTaken) return _tasks; - else throw new NotSupportedException(); - } - finally - { - if (lockTaken) Monitor.Exit(_tasks); - } - } - } -} http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net/Support/ReaderWriterLockSlimExtensions.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net/Support/ReaderWriterLockSlimExtensions.cs b/src/Lucene.Net/Support/ReaderWriterLockSlimExtensions.cs deleted file mode 100644 index d3f4271..0000000 --- a/src/Lucene.Net/Support/ReaderWriterLockSlimExtensions.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System; -using System.Threading; - -namespace Lucene.Net.Support -{ - /* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - /// <summary> - /// Extensions to help obtain/release from a ReaderWriterSlimLock. - /// Taken from: - /// http://stackoverflow.com/questions/170028/how-would-you-simplify-entering-and-exiting-a-readerwriterlock - /// - /// LUCENENET specific - /// </summary> - internal static class ReaderWriterLockSlimExtensions - { - sealed class ReadLockToken : IDisposable - { - private ReaderWriterLockSlim _readerWriterLockSlim; - - public ReadLockToken(ReaderWriterLockSlim sync) - { - _readerWriterLockSlim = sync; - sync.EnterReadLock(); - } - - public void Dispose() - { - if (_readerWriterLockSlim != null) - { - _readerWriterLockSlim.ExitReadLock(); - _readerWriterLockSlim = null; - } - } - } - - sealed class WriteLockToken : IDisposable - { - private ReaderWriterLockSlim _readerWriterLockSlim; - - public WriteLockToken(ReaderWriterLockSlim sync) - { - _readerWriterLockSlim = sync; - sync.EnterWriteLock(); - } - - public void Dispose() - { - if (_readerWriterLockSlim != null) - { - _readerWriterLockSlim.ExitWriteLock(); - _readerWriterLockSlim = null; - } - } - } - - public static IDisposable Read(this ReaderWriterLockSlim obj) - { - return new ReadLockToken(obj); - } - - public static IDisposable Write(this ReaderWriterLockSlim obj) - { - return new WriteLockToken(obj); - } - } -} http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net/Support/ReentrantLock.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net/Support/ReentrantLock.cs b/src/Lucene.Net/Support/ReentrantLock.cs deleted file mode 100644 index 7691d04..0000000 --- a/src/Lucene.Net/Support/ReentrantLock.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System.Threading; - -namespace Lucene.Net.Support -{ - /* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - public class ReentrantLock - { - // .NET Port: lock object used to emulate ReentrantLock - private readonly object _lock = new object(); - - // .NET Port: Estimated monitor queue length - private int _queueLength = 0; - - // .NET Port: mimic ReentrantLock -- Monitor is re-entrant - public void Lock() - { - // note about queue length: in java's ReentrantLock, getQueueLength() returns the number - // of threads waiting on entering the lock. So here, we're incrementing the count before trying to enter, - // meaning that until enter has completed the thread is waiting so the queue is incremented. Once - // we enter the lock, then we immediately decrement it because that thread is no longer in the queue. - // Due to race conditions, the queue length is an estimate only. - Interlocked.Increment(ref _queueLength); - Monitor.Enter(_lock); - Interlocked.Decrement(ref _queueLength); - } - - // .NET Port: mimic ReentrantLock -- Monitor is re-entrant - public void Unlock() - { - Monitor.Exit(_lock); - } - - public bool TryLock() - { - Interlocked.Increment(ref _queueLength); - bool success = Monitor.TryEnter(_lock); - Interlocked.Decrement(ref _queueLength); - - return success; - } - - public int QueueLength - { - get - { - // hold onto the estimate for the length of this method - int estimate = _queueLength; - - // should never be < 0, but just in case, as a negative number doesn't make sense. - return estimate <= 0 ? 0 : estimate; - } - } - - public bool HasQueuedThreads - { - get { return _queueLength > 0; } - } - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net/Support/TaskSchedulerCompletionService.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net/Support/TaskSchedulerCompletionService.cs b/src/Lucene.Net/Support/TaskSchedulerCompletionService.cs deleted file mode 100644 index 487aa95..0000000 --- a/src/Lucene.Net/Support/TaskSchedulerCompletionService.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Lucene.Net.Support -{ - /* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - public class TaskSchedulerCompletionService<T> : ICompletionService<T> - { - private readonly TaskFactory<T> factory; - private readonly Queue<Task<T>> taskQueue = new Queue<Task<T>>(); - - public TaskSchedulerCompletionService(TaskScheduler scheduler) - { - this.factory = new TaskFactory<T>(scheduler ?? TaskScheduler.Default); - } - - public Task<T> Submit(ICallable<T> task) - { - var t = factory.StartNew(task.Call); - taskQueue.Enqueue(t); - return t; - } - - public Task<T> Take() - { - return taskQueue.Dequeue(); - } - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net/Support/ThreadClass.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net/Support/ThreadClass.cs b/src/Lucene.Net/Support/ThreadClass.cs deleted file mode 100644 index 87efe99..0000000 --- a/src/Lucene.Net/Support/ThreadClass.cs +++ /dev/null @@ -1,331 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * -*/ - -using System; -using System.Threading; - -namespace Lucene.Net.Support -{ - /// <summary> - /// Support class used to handle threads - /// </summary> - public class ThreadClass : IThreadRunnable - { - /// <summary> - /// The instance of System.Threading.Thread - /// </summary> - private Thread _threadField; - - /// <summary> - /// Initializes a new instance of the ThreadClass class - /// </summary> - public ThreadClass() - { - _threadField = new Thread(Run); - } - - /// <summary> - /// Initializes a new instance of the Thread class. - /// </summary> - /// <param name="name">The name of the thread</param> - public ThreadClass(string name) - { - _threadField = new Thread(Run); - this.Name = name; - } - - /// <summary> - /// Initializes a new instance of the Thread class. - /// </summary> - /// <param name="start">A ThreadStart delegate that references the methods to be invoked when this thread begins executing</param> - public ThreadClass(ThreadStart start) - { - _threadField = new Thread(start); - } - - /// <summary> - /// Initializes a new instance of the Thread class. - /// </summary> - /// <param name="start">A ThreadStart delegate that references the methods to be invoked when this thread begins executing</param> - /// <param name="name">The name of the thread</param> - public ThreadClass(ThreadStart start, string name) - { - _threadField = new Thread(start); - this.Name = name; - } - - /// <summary> - /// This method has no functionality unless the method is overridden - /// </summary> - public virtual void Run() - { - } - - /// <summary> - /// Causes the operating system to change the state of the current thread instance to ThreadState.Running - /// </summary> - public virtual void Start() - { - _threadField.Start(); - } - - /// <summary> - /// Interrupts a thread that is in the WaitSleepJoin thread state - /// </summary> - public virtual void Interrupt() - { -#if !NETSTANDARD - _threadField.Interrupt(); -#endif - } - - /// <summary> - /// Gets the current thread instance - /// </summary> - public System.Threading.Thread Instance - { - get - { - return _threadField; - } - set - { - _threadField = value; - } - } - - /// <summary> - /// Gets or sets the name of the thread - /// </summary> - public String Name - { - get - { - return _threadField.Name; - } - set - { - if (_threadField.Name == null) - _threadField.Name = value; - } - } - - public void SetDaemon(bool isDaemon) - { - _threadField.IsBackground = isDaemon; - } - -#if !NETSTANDARD - /// <summary> - /// Gets or sets a value indicating the scheduling priority of a thread - /// </summary> - public ThreadPriority Priority - { - get - { - try - { - return _threadField.Priority; - } - catch - { - return ThreadPriority.Normal; - } - } - set - { - try - { - _threadField.Priority = value; - } - catch { } - } - } -#endif - - /// <summary> - /// Gets a value indicating the execution status of the current thread - /// </summary> - public bool IsAlive - { - get - { - return _threadField.IsAlive; - } - } - - /// <summary> - /// Gets or sets a value indicating whether or not a thread is a background thread. - /// </summary> - public bool IsBackground - { - get - { - return _threadField.IsBackground; - } - set - { - _threadField.IsBackground = value; - } - } - - /// <summary> - /// Blocks the calling thread until a thread terminates - /// </summary> - public void Join() - { - _threadField.Join(); - } - - /// <summary> - /// Blocks the calling thread until a thread terminates or the specified time elapses - /// </summary> - /// <param name="milliSeconds">Time of wait in milliseconds</param> - public void Join(long milliSeconds) - { - _threadField.Join(Convert.ToInt32(milliSeconds)); - } - - /// <summary> - /// Blocks the calling thread until a thread terminates or the specified time elapses - /// </summary> - /// <param name="milliSeconds">Time of wait in milliseconds</param> - /// <param name="nanoSeconds">Time of wait in nanoseconds</param> - public void Join(long milliSeconds, int nanoSeconds) - { - int totalTime = Convert.ToInt32(milliSeconds + (nanoSeconds*0.000001)); - - _threadField.Join(totalTime); - } - - /// <summary> - /// Resumes a thread that has been suspended - /// </summary> - public void Resume() - { - Monitor.PulseAll(_threadField); - } - -#if !NETSTANDARD - - /// <summary> - /// Raises a ThreadAbortException in the thread on which it is invoked, - /// to begin the process of terminating the thread. Calling this method - /// usually terminates the thread - /// </summary> - public void Abort() - { - _threadField.Abort(); - } - - /// <summary> - /// Raises a ThreadAbortException in the thread on which it is invoked, - /// to begin the process of terminating the thread while also providing - /// exception information about the thread termination. - /// Calling this method usually terminates the thread. - /// </summary> - /// <param name="stateInfo">An object that contains application-specific information, such as state, which can be used by the thread being aborted</param> - public void Abort(object stateInfo) - { - _threadField.Abort(stateInfo); - } -#endif - - /// <summary> - /// Suspends the thread, if the thread is already suspended it has no effect - /// </summary> - public void Suspend() - { - Monitor.Wait(_threadField); - } - - /// <summary> - /// Obtain a String that represents the current object - /// </summary> - /// <returns>A String that represents the current object</returns> - public override System.String ToString() - { -#if !NETSTANDARD - return "Thread[" + Name + "," + Priority.ToString() + "]"; -#else - return "Thread[" + Name + "]"; -#endif - } - - [ThreadStatic] - private static ThreadClass This = null; - - // named as the Java version - public static ThreadClass CurrentThread() - { - return Current(); - } - - public static void Sleep(long ms) - { - // casting long ms to int ms could lose resolution, however unlikely - // that someone would want to sleep for that long... - Thread.Sleep((int)ms); - } - - /// <summary> - /// Gets the currently running thread - /// </summary> - /// <returns>The currently running thread</returns> - public static ThreadClass Current() - { - if (This == null) - { - This = new ThreadClass(); - This.Instance = Thread.CurrentThread; - } - return This; - } - - public static bool operator ==(ThreadClass t1, object t2) - { - if (((object)t1) == null) return t2 == null; - return t1.Equals(t2); - } - - public static bool operator !=(ThreadClass t1, object t2) - { - return !(t1 == t2); - } - - public override bool Equals(object obj) - { - if (obj == null) return false; - if (obj is ThreadClass) return this._threadField.Equals(((ThreadClass)obj)._threadField); - return false; - } - - public override int GetHashCode() - { - return this._threadField.GetHashCode(); - } - - public ThreadState State - { - get { return _threadField.ThreadState; } - } - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net/Support/ThreadFactory.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net/Support/ThreadFactory.cs b/src/Lucene.Net/Support/ThreadFactory.cs deleted file mode 100644 index df92198..0000000 --- a/src/Lucene.Net/Support/ThreadFactory.cs +++ /dev/null @@ -1,32 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * -*/ - -// LUCENENET NOTE: The only class that depends on this is NamedThreadFactory, which is Java-specific, so this is being excluded. - -//using System.Threading; - -//namespace Lucene.Net.Support -//{ -// public abstract class ThreadFactory -// { -// public abstract Thread NewThread(IThreadRunnable r); -// } -//} http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net/Support/ThreadLock.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net/Support/ThreadLock.cs b/src/Lucene.Net/Support/ThreadLock.cs deleted file mode 100644 index b337050..0000000 --- a/src/Lucene.Net/Support/ThreadLock.cs +++ /dev/null @@ -1,83 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * -*/ - -using System.Threading; - -namespace Lucene.Net.Support -{ - /// <summary> - /// Abstract base class that provides a synchronization interface - /// for derived lock types - /// </summary> - public abstract class ThreadLock - { - public abstract void Enter(object obj); - - public abstract void Exit(object obj); - - private static readonly ThreadLock _nullLock = new NullThreadLock(); - private static readonly ThreadLock _monitorLock = new MonitorThreadLock(); - - /// <summary> - /// A ThreadLock class that actually does no locking - /// Used in ParallelMultiSearcher/MultiSearcher - /// </summary> - public static ThreadLock NullLock - { - get { return _nullLock; } - } - - /// <summary> - /// Wrapper class for the Monitor Enter/Exit methods - /// using the <see cref="ThreadLock"/> interface - /// </summary> - public static ThreadLock MonitorLock - { - get { return _monitorLock; } - } - - private sealed class NullThreadLock : ThreadLock - { - public override void Enter(object obj) - { - // Do nothing - } - - public override void Exit(object obj) - { - // Do nothing - } - } - - private sealed class MonitorThreadLock : ThreadLock - { - public override void Enter(object obj) - { - Monitor.Enter(obj); - } - - public override void Exit(object obj) - { - Monitor.Exit(obj); - } - } - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net/Support/Threading/CloseableThreadLocalProfiler.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net/Support/Threading/CloseableThreadLocalProfiler.cs b/src/Lucene.Net/Support/Threading/CloseableThreadLocalProfiler.cs new file mode 100644 index 0000000..8423793 --- /dev/null +++ b/src/Lucene.Net/Support/Threading/CloseableThreadLocalProfiler.cs @@ -0,0 +1,45 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +using System; + +namespace Lucene.Net.Support.Threading +{ + /// <summary> + /// For Debuging purposes. + /// </summary> + public class DisposableThreadLocalProfiler + { + private static bool _enableIDisposableThreadLocalProfiler = false; + public static System.Collections.Generic.List<WeakReference> Instances = new System.Collections.Generic.List<WeakReference>(); + + public static bool EnableIDisposableThreadLocalProfiler + { + get { return _enableIDisposableThreadLocalProfiler; } + set + { + _enableIDisposableThreadLocalProfiler = value; + lock (Instances) + Instances.Clear(); + } + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net/Support/Threading/ICompletionService.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net/Support/Threading/ICompletionService.cs b/src/Lucene.Net/Support/Threading/ICompletionService.cs new file mode 100644 index 0000000..7de4e66 --- /dev/null +++ b/src/Lucene.Net/Support/Threading/ICompletionService.cs @@ -0,0 +1,32 @@ +using System.Threading.Tasks; + +namespace Lucene.Net.Support.Threading +{ + /* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + public interface ICompletionService<V> + { + //Task<V> Poll(); + + //Task<V> Poll(long timeout, TimeUnit unit); + + Task<V> Submit(ICallable<V> task); + + Task<V> Take(); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net/Support/Threading/IThreadRunnable.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net/Support/Threading/IThreadRunnable.cs b/src/Lucene.Net/Support/Threading/IThreadRunnable.cs new file mode 100644 index 0000000..ab29921 --- /dev/null +++ b/src/Lucene.Net/Support/Threading/IThreadRunnable.cs @@ -0,0 +1,36 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +namespace Lucene.Net.Support.Threading +{ + /// <summary> + /// this interface should be implemented by any class whose instances are intended + /// to be executed by a thread. + /// </summary> + public interface IThreadRunnable + { + /// <summary> + /// this method has to be implemented in order that starting of the thread causes the object's + /// run method to be called in that separately executing thread. + /// </summary> + void Run(); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net/Support/Threading/LimitedConcurrencyLevelTaskScheduler.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net/Support/Threading/LimitedConcurrencyLevelTaskScheduler.cs b/src/Lucene.Net/Support/Threading/LimitedConcurrencyLevelTaskScheduler.cs new file mode 100644 index 0000000..71671af --- /dev/null +++ b/src/Lucene.Net/Support/Threading/LimitedConcurrencyLevelTaskScheduler.cs @@ -0,0 +1,187 @@ +/* +MICROSOFT LIMITED PUBLIC LICENSE version 1.1 +This license governs use of code marked as "sample" or "example" available on this web site +without a license agreement, as provided under the section above titled +"NOTICE SPECIFIC TO SOFTWARE AVAILABLE ON THIS WEB SITE." If you use such +code (the "software"), you accept this license. If you do not accept the +license, do not use the software. + +1. Definitions +The terms "reproduce," "reproduction," "derivative works," and "distribution" have the +same meaning here as under U.S. copyright law. +A "contribution" is the original software, or any additions or changes to the software. +A "contributor" is any person that distributes its contribution under this license. +"Licensed patents" are a contributorâs patent claims that read directly on its contribution. + +2. Grant of Rights +(A) Copyright Grant - Subject to the terms of this license, including the license conditions +and limitations in section 3, each contributor grants you a non-exclusive, worldwide, +royalty-free copyright license to reproduce its contribution, prepare derivative works +of its contribution, and distribute its contribution or any derivative works that you create. +(B) Patent Grant - Subject to the terms of this license, including the license conditions +and limitations in section 3, each contributor grants you a non-exclusive, worldwide, +royalty-free license under its licensed patents to make, have made, use, sell, +offer for sale, import, and/or otherwise dispose of its contribution in the +software or derivative works of the contribution in the software. + +3. Conditions and Limitations +(A) No Trademark License- This license does not grant you rights to use any contributorsâ +name, logo, or trademarks. +(B) If you bring a patent claim against any contributor over patents that you claim are +infringed by the software, your patent license from such contributor to the software +ends automatically. +(C) If you distribute any portion of the software, you must retain all copyright, patent, +trademark, and attribution notices that are present in the software. +(D) If you distribute any portion of the software in source code form, you may do so only +under this license by including a complete copy of this license with your distribution. +If you distribute any portion of the software in compiled or object code form, you may +only do so under a license that complies with this license. +(E) The software is licensed "as-is." You bear the risk of using it. The contributors +give no express warranties, guarantees or conditions. You may have additional consumer +rights under your local laws which this license cannot change. To the extent permitted +under your local laws, the contributors exclude the implied warranties of merchantability, +fitness for a particular purpose and non-infringement. +(F) Platform Limitation - The licenses granted in sections 2(A) and 2(B) extend only +to the software or derivative works that you create that run directly on a Microsoft +Windows operating system product, Microsoft run-time technology (such as the .NET +Framework or Silverlight), or Microsoft application platform (such as Microsoft +Office or Microsoft Dynamics). +*/ + +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace Lucene.Net.Support.Threading +{ + /// <summary> + /// Provides a task scheduler that ensures a maximum concurrency level while + /// running on top of the thread pool. + /// + /// Source: https://msdn.microsoft.com/en-us/library/system.threading.tasks.taskscheduler(v=vs.110).aspx + /// </summary> + public class LimitedConcurrencyLevelTaskScheduler : TaskScheduler + { + // Indicates whether the current thread is processing work items. + [ThreadStatic] + private static bool _currentThreadIsProcessingItems; + + // The list of tasks to be executed + private readonly LinkedList<Task> _tasks = new LinkedList<Task>(); // protected by lock(_tasks) + + // The maximum concurrency level allowed by this scheduler. + private readonly int _maxDegreeOfParallelism; + + // Indicates whether the scheduler is currently processing work items. + private int _delegatesQueuedOrRunning = 0; + + // Creates a new instance with the specified degree of parallelism. + public LimitedConcurrencyLevelTaskScheduler(int maxDegreeOfParallelism) + { + if (maxDegreeOfParallelism < 1) throw new ArgumentOutOfRangeException("maxDegreeOfParallelism"); + _maxDegreeOfParallelism = maxDegreeOfParallelism; + } + + // Queues a task to the scheduler. + protected sealed override void QueueTask(Task task) + { + // Add the task to the list of tasks to be processed. If there aren't enough + // delegates currently queued or running to process tasks, schedule another. + lock (_tasks) + { + _tasks.AddLast(task); + if (_delegatesQueuedOrRunning < _maxDegreeOfParallelism) + { + ++_delegatesQueuedOrRunning; + NotifyThreadPoolOfPendingWork(); + } + } + } + + // Inform the ThreadPool that there's work to be executed for this scheduler. + private void NotifyThreadPoolOfPendingWork() + { +#if FEATURE_THREADPOOL_UNSAFEQUEUEWORKITEM + ThreadPool.UnsafeQueueUserWorkItem( +#else + ThreadPool.QueueUserWorkItem( +#endif + _ => + { + // Note that the current thread is now processing work items. + // This is necessary to enable inlining of tasks into this thread. + _currentThreadIsProcessingItems = true; + try + { + // Process all available items in the queue. + while (true) + { + Task item; + lock (_tasks) + { + // When there are no more items to be processed, + // note that we're done processing, and get out. + if (_tasks.Count == 0) + { + --_delegatesQueuedOrRunning; + break; + } + + // Get the next item from the queue + item = _tasks.First.Value; + _tasks.Remove(item); + } + + // Execute the task we pulled out of the queue + base.TryExecuteTask(item); + } + } + // We're done processing items on the current thread + finally { _currentThreadIsProcessingItems = false; } + }, null); + } + + // Attempts to execute the specified task on the current thread. + protected sealed override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued) + { + // If this thread isn't already processing a task, we don't support inlining + if (!_currentThreadIsProcessingItems) return false; + + // If the task was previously queued, remove it from the queue + if (taskWasPreviouslyQueued) + // Try to run the task. + if (TryDequeue(task)) + return base.TryExecuteTask(task); + else + return false; + else + return base.TryExecuteTask(task); + } + + // Attempt to remove a previously scheduled task from the scheduler. + protected sealed override bool TryDequeue(Task task) + { + lock (_tasks) return _tasks.Remove(task); + } + + // Gets the maximum concurrency level supported by this scheduler. + public sealed override int MaximumConcurrencyLevel { get { return _maxDegreeOfParallelism; } } + + // Gets an enumerable of the tasks currently scheduled on this scheduler. + protected sealed override IEnumerable<Task> GetScheduledTasks() + { + bool lockTaken = false; + try + { + Monitor.TryEnter(_tasks, ref lockTaken); + if (lockTaken) return _tasks; + else throw new NotSupportedException(); + } + finally + { + if (lockTaken) Monitor.Exit(_tasks); + } + } + } +} http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net/Support/Threading/ReaderWriterLockSlimExtensions.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net/Support/Threading/ReaderWriterLockSlimExtensions.cs b/src/Lucene.Net/Support/Threading/ReaderWriterLockSlimExtensions.cs new file mode 100644 index 0000000..c760da3 --- /dev/null +++ b/src/Lucene.Net/Support/Threading/ReaderWriterLockSlimExtensions.cs @@ -0,0 +1,82 @@ +using System; +using System.Threading; + +namespace Lucene.Net.Support.Threading +{ + /* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + /// <summary> + /// Extensions to help obtain/release from a ReaderWriterSlimLock. + /// Taken from: + /// http://stackoverflow.com/questions/170028/how-would-you-simplify-entering-and-exiting-a-readerwriterlock + /// + /// LUCENENET specific + /// </summary> + internal static class ReaderWriterLockSlimExtensions + { + sealed class ReadLockToken : IDisposable + { + private ReaderWriterLockSlim _readerWriterLockSlim; + + public ReadLockToken(ReaderWriterLockSlim sync) + { + _readerWriterLockSlim = sync; + sync.EnterReadLock(); + } + + public void Dispose() + { + if (_readerWriterLockSlim != null) + { + _readerWriterLockSlim.ExitReadLock(); + _readerWriterLockSlim = null; + } + } + } + + sealed class WriteLockToken : IDisposable + { + private ReaderWriterLockSlim _readerWriterLockSlim; + + public WriteLockToken(ReaderWriterLockSlim sync) + { + _readerWriterLockSlim = sync; + sync.EnterWriteLock(); + } + + public void Dispose() + { + if (_readerWriterLockSlim != null) + { + _readerWriterLockSlim.ExitWriteLock(); + _readerWriterLockSlim = null; + } + } + } + + public static IDisposable Read(this ReaderWriterLockSlim obj) + { + return new ReadLockToken(obj); + } + + public static IDisposable Write(this ReaderWriterLockSlim obj) + { + return new WriteLockToken(obj); + } + } +} http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net/Support/Threading/ReentrantLock.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net/Support/Threading/ReentrantLock.cs b/src/Lucene.Net/Support/Threading/ReentrantLock.cs new file mode 100644 index 0000000..7e4eea3 --- /dev/null +++ b/src/Lucene.Net/Support/Threading/ReentrantLock.cs @@ -0,0 +1,75 @@ +using System.Threading; + +namespace Lucene.Net.Support.Threading +{ + /* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + public class ReentrantLock + { + // .NET Port: lock object used to emulate ReentrantLock + private readonly object _lock = new object(); + + // .NET Port: Estimated monitor queue length + private int _queueLength = 0; + + // .NET Port: mimic ReentrantLock -- Monitor is re-entrant + public void Lock() + { + // note about queue length: in java's ReentrantLock, getQueueLength() returns the number + // of threads waiting on entering the lock. So here, we're incrementing the count before trying to enter, + // meaning that until enter has completed the thread is waiting so the queue is incremented. Once + // we enter the lock, then we immediately decrement it because that thread is no longer in the queue. + // Due to race conditions, the queue length is an estimate only. + Interlocked.Increment(ref _queueLength); + Monitor.Enter(_lock); + Interlocked.Decrement(ref _queueLength); + } + + // .NET Port: mimic ReentrantLock -- Monitor is re-entrant + public void Unlock() + { + Monitor.Exit(_lock); + } + + public bool TryLock() + { + Interlocked.Increment(ref _queueLength); + bool success = Monitor.TryEnter(_lock); + Interlocked.Decrement(ref _queueLength); + + return success; + } + + public int QueueLength + { + get + { + // hold onto the estimate for the length of this method + int estimate = _queueLength; + + // should never be < 0, but just in case, as a negative number doesn't make sense. + return estimate <= 0 ? 0 : estimate; + } + } + + public bool HasQueuedThreads + { + get { return _queueLength > 0; } + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/lucenenet/blob/00b95661/src/Lucene.Net/Support/Threading/TaskSchedulerCompletionService.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net/Support/Threading/TaskSchedulerCompletionService.cs b/src/Lucene.Net/Support/Threading/TaskSchedulerCompletionService.cs new file mode 100644 index 0000000..fcc8605 --- /dev/null +++ b/src/Lucene.Net/Support/Threading/TaskSchedulerCompletionService.cs @@ -0,0 +1,45 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Lucene.Net.Support.Threading +{ + /* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + public class TaskSchedulerCompletionService<T> : ICompletionService<T> + { + private readonly TaskFactory<T> factory; + private readonly Queue<Task<T>> taskQueue = new Queue<Task<T>>(); + + public TaskSchedulerCompletionService(TaskScheduler scheduler) + { + this.factory = new TaskFactory<T>(scheduler ?? TaskScheduler.Default); + } + + public Task<T> Submit(ICallable<T> task) + { + var t = factory.StartNew(task.Call); + taskQueue.Enqueue(t); + return t; + } + + public Task<T> Take() + { + return taskQueue.Dequeue(); + } + } +} \ No newline at end of file
