//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test void concurrentlyPublishedEventsMustAllBeProcessed() internal virtual void ConcurrentlyPublishedEventsMustAllBeProcessed() { assertTimeout(ofSeconds(10), () => { EventConsumer consumer = new EventConsumer(); System.Threading.CountdownEvent startLatch = new System.Threading.CountdownEvent(1); const int threads = 10; const int iterations = 2_000; AsyncEvents <Event> asyncEvents = new AsyncEvents <Event>(consumer, AsyncEvents.Monitor_Fields.None); _executor.submit(asyncEvents); ExecutorService threadPool = Executors.newFixedThreadPool(threads); ThreadStart runner = () => { try { startLatch.await(); } catch (InterruptedException e) { throw new Exception(e); } for (int i = 0; i < iterations; i++) { asyncEvents.Send(new Event()); } }; for (int i = 0; i < threads; i++) { threadPool.submit(runner); } startLatch.countDown(); Thread thisThread = Thread.CurrentThread; int eventCount = threads * iterations; try { for (int i = 0; i < eventCount; i++) { Event @event = consumer.Poll(1, TimeUnit.SECONDS); if (@event == null) { i--; } else { assertThat(@event.ProcessedBy, @is(not(thisThread))); } } } finally { asyncEvents.Shutdown(); threadPool.shutdown(); } }); }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @RepeatedTest(50) void writeLockingCursorMustThrowWhenLockingPageRacesWithUnmapping() internal virtual void WriteLockingCursorMustThrowWhenLockingPageRacesWithUnmapping() { assertTimeout(ofMillis(SEMI_LONG_TIMEOUT_MILLIS), () => { // Even if we block in pin, waiting to grab a lock on a page that is // already locked, and the PagedFile is concurrently closed, then we // want to have an exception thrown, such that we race and get a // page that is writable after the PagedFile has been closed. // This is important because closing a PagedFile implies flushing, thus // ensuring that all changes make it to storage. // Conversely, we don't have to go to the same lengths for read locked // pages, because those are never changed. Not by us, anyway. File file = file("a"); generateFileWithRecords(file, recordsPerFilePage * 2, recordSize); getPageCache(fs, maxPages, PageCacheTracer.NULL, PageCursorTracerSupplier.NULL); PagedFile pf = pageCache.map(file, filePageSize); System.Threading.CountdownEvent hasLockLatch = new System.Threading.CountdownEvent(1); System.Threading.CountdownEvent unlockLatch = new System.Threading.CountdownEvent(1); System.Threading.CountdownEvent secondThreadGotLockLatch = new System.Threading.CountdownEvent(1); AtomicBoolean doneWriteSignal = new AtomicBoolean(); AtomicBoolean doneCloseSignal = new AtomicBoolean(); executor.submit(() => { using (PageCursor cursor = pf.Io(0, PF_SHARED_WRITE_LOCK)) { cursor.Next(); hasLockLatch.countDown(); unlockLatch.await(); } return(null); }); hasLockLatch.await(); // A write lock is now held on page 0. Future <object> takeLockFuture = executor.submit(() => { using (PageCursor cursor = pf.Io(0, PF_SHARED_WRITE_LOCK)) { cursor.Next(); doneWriteSignal.set(true); secondThreadGotLockLatch.await(); } return(null); }); Future <object> closeFuture = executor.submit(() => { pf.Close(); doneCloseSignal.set(true); return(null); }); try { Thread.yield(); closeFuture.get(50, TimeUnit.MILLISECONDS); fail("Expected a TimeoutException here"); } catch (TimeoutException) { // As expected, the close cannot not complete while an write // lock is held } // Now, both the close action and a grab for an write page lock is // waiting for our first thread. // When we release that lock, we should see that either close completes // and our second thread, the one blocked on the write lock, gets an // exception, or we should see that the second thread gets the lock, // and then close has to wait for that thread as well. unlockLatch.countDown(); // The race is on. bool anyDone; do { Thread.yield(); anyDone = doneWriteSignal.get() | doneCloseSignal.get(); } while (!anyDone); if (doneCloseSignal.get()) { closeFuture.get(1000, TimeUnit.MILLISECONDS); // The closeFuture got it first, so the takeLockFuture should throw. try { secondThreadGotLockLatch.countDown(); // only to prevent incorrect programs from deadlocking takeLockFuture.get(); fail("Expected takeLockFuture.get() to throw an ExecutionException"); } catch (ExecutionException e) { Exception cause = e.InnerException; assertThat(cause, instanceOf(typeof(FileIsNotMappedException))); assertThat(cause.Message, startsWith("File has been unmapped")); } } else { assertTrue(doneWriteSignal.get()); // The takeLockFuture got it first, so the closeFuture should // complete when we release the latch. secondThreadGotLockLatch.countDown(); closeFuture.get(20000, TimeUnit.MILLISECONDS); } }); }
public override void rotationCompleted(Stream @out) { _latch.countDown(); }