public void read( final long position, final long size, final ByteBuffer directByteBuffer, final AIOCallback aioPackage) throws HornetQException { checkOpened(); if (poller == null) { startPoller(); } pendingWrites.countUp(); maxIOSemaphore.acquireUninterruptibly(); try { read(handler, position, size, directByteBuffer, aioPackage); } catch (HornetQException e) { // Release only if an exception happened maxIOSemaphore.release(); pendingWrites.countDown(); throw e; } catch (RuntimeException e) { // Release only if an exception happened maxIOSemaphore.release(); pendingWrites.countDown(); throw e; } }
/* (non-Javadoc) * @see org.hornetq.jms.example.ClientAbstract#onCommit() */ @Override protected void onCommit() { msgs += pendingMsgs; this.currentDiff.addAndGet(-pendingMsgs); latchMax.countDown(pendingMsgs); pendingMsgs = 0; }
private void callbackDone( final AIOCallback callback, final long sequence, final ByteBuffer buffer) { maxIOSemaphore.release(); pendingWrites.countDown(); callbackLock.lock(); try { if (sequence == -1) { callback.done(); } else { if (sequence == nextReadSequence) { nextReadSequence++; callback.done(); flushCallbacks(); } else { pendingCallbacks.add(new CallbackHolder(sequence, callback)); } } // The buffer is not sent on callback for read operations if (bufferCallback != null && buffer != null) { bufferCallback.bufferDone(buffer); } } finally { callbackLock.unlock(); } }
@Test public void testLatchWithParameterizedDown() throws Exception { ReusableLatch latch = new ReusableLatch(1000); latch.countDown(5000); assertTrue(latch.await(1000)); assertEquals(0, latch.getCount()); }
@Test public void testLatchOnSingleThread() throws Exception { ReusableLatch latch = new ReusableLatch(); for (int i = 1; i <= 100; i++) { latch.countUp(); Assert.assertEquals(i, latch.getCount()); } for (int i = 100; i > 0; i--) { Assert.assertEquals(i, latch.getCount()); latch.countDown(); Assert.assertEquals(i - 1, latch.getCount()); } latch.await(); }
@Override public boolean intercept(final Packet packet, final RemotingConnection connection) throws HornetQException { if (packet instanceof SessionReceiveMessage) { System.out.println("Receiving message"); try { reusableLatch.countDown(); semaphore.acquire(); semaphore.release(); reusableLatch.countUp(); } catch (Exception e) { e.printStackTrace(); } } if (pendingException != null) { HornetQException exToThrow = pendingException; pendingException = null; throw exToThrow; } return true; }
// Called by the JNI layer.. just ignore the // warning private void callbackError( final AIOCallback callback, final long sequence, final ByteBuffer buffer, final int errorCode, final String errorMessage) { HornetQJournalLogger.LOGGER.callbackError(errorMessage); fireExceptionListener(errorCode, errorMessage); maxIOSemaphore.release(); pendingWrites.countDown(); callbackLock.lock(); try { if (sequence == -1) { callback.onError(errorCode, errorMessage); } else { if (sequence == nextReadSequence) { nextReadSequence++; callback.onError(errorCode, errorMessage); flushCallbacks(); } else { pendingCallbacks.add(new ErrorCallback(sequence, callback, errorCode, errorMessage)); } } } finally { callbackLock.unlock(); } // The buffer is not sent on callback for read operations if (bufferCallback != null && buffer != null) { bufferCallback.bufferDone(buffer); } }
/** * This test will open numberOfThreads threads, and add numberOfAdds on the VariableLatch After * those addthreads are finished, the latch count should be numberOfThreads * numberOfAdds Then it * will open numberOfThreads threads again releasing numberOfAdds on the VariableLatch After those * releaseThreads are finished, the latch count should be 0 And all the waiting threads should be * finished also * * @throws Exception */ @Test public void testLatchOnMultiThread() throws Exception { final ReusableLatch latch = new ReusableLatch(); latch.countUp(); // We hold at least one, so ThreadWaits won't go away final int numberOfThreads = 100; final int numberOfAdds = 100; class ThreadWait extends Thread { private volatile boolean waiting = true; @Override public void run() { try { if (!latch.await(5000)) { UnitTestLogger.LOGGER.error("Latch timed out"); } } catch (Exception e) { UnitTestLogger.LOGGER.error(e); } waiting = false; } } class ThreadAdd extends Thread { private final CountDownLatch latchReady; private final CountDownLatch latchStart; ThreadAdd(final CountDownLatch latchReady, final CountDownLatch latchStart) { this.latchReady = latchReady; this.latchStart = latchStart; } @Override public void run() { try { latchReady.countDown(); // Everybody should start at the same time, to worse concurrency // effects latchStart.await(); for (int i = 0; i < numberOfAdds; i++) { latch.countUp(); } } catch (Exception e) { UnitTestLogger.LOGGER.error(e.getMessage(), e); } } } CountDownLatch latchReady = new CountDownLatch(numberOfThreads); CountDownLatch latchStart = new CountDownLatch(1); ThreadAdd[] threadAdds = new ThreadAdd[numberOfThreads]; ThreadWait waits[] = new ThreadWait[numberOfThreads]; for (int i = 0; i < numberOfThreads; i++) { threadAdds[i] = new ThreadAdd(latchReady, latchStart); threadAdds[i].start(); waits[i] = new ThreadWait(); waits[i].start(); } latchReady.await(); latchStart.countDown(); for (int i = 0; i < numberOfThreads; i++) { threadAdds[i].join(); } for (int i = 0; i < numberOfThreads; i++) { Assert.assertTrue(waits[i].waiting); } Assert.assertEquals(numberOfThreads * numberOfAdds + 1, latch.getCount()); class ThreadDown extends Thread { private final CountDownLatch latchReady; private final CountDownLatch latchStart; ThreadDown(final CountDownLatch latchReady, final CountDownLatch latchStart) { this.latchReady = latchReady; this.latchStart = latchStart; } @Override public void run() { try { latchReady.countDown(); // Everybody should start at the same time, to worse concurrency // effects latchStart.await(); for (int i = 0; i < numberOfAdds; i++) { latch.countDown(); } } catch (Exception e) { UnitTestLogger.LOGGER.error(e.getMessage(), e); } } } latchReady = new CountDownLatch(numberOfThreads); latchStart = new CountDownLatch(1); ThreadDown down[] = new ThreadDown[numberOfThreads]; for (int i = 0; i < numberOfThreads; i++) { down[i] = new ThreadDown(latchReady, latchStart); down[i].start(); } latchReady.await(); latchStart.countDown(); for (int i = 0; i < numberOfThreads; i++) { down[i].join(); } Assert.assertEquals(1, latch.getCount()); for (int i = 0; i < numberOfThreads; i++) { Assert.assertTrue(waits[i].waiting); } latch.countDown(); for (int i = 0; i < numberOfThreads; i++) { waits[i].join(); } Assert.assertEquals(0, latch.getCount()); for (int i = 0; i < numberOfThreads; i++) { Assert.assertFalse(waits[i].waiting); } }
@Test public void testReuseLatch() throws Exception { final ReusableLatch latch = new ReusableLatch(5); for (int i = 0; i < 5; i++) { latch.countDown(); } latch.countUp(); class ThreadWait extends Thread { private volatile boolean waiting = false; private volatile Exception e; private final CountDownLatch readyLatch = new CountDownLatch(1); @Override public void run() { waiting = true; readyLatch.countDown(); try { if (!latch.await(1000)) { UnitTestLogger.LOGGER.error("Latch timed out!", new Exception("trace")); } } catch (Exception e) { UnitTestLogger.LOGGER.error(e); this.e = e; } waiting = false; } } ThreadWait t = new ThreadWait(); t.start(); t.readyLatch.await(); Assert.assertEquals(true, t.waiting); latch.countDown(); t.join(); Assert.assertEquals(false, t.waiting); Assert.assertNull(t.e); latch.countUp(); t = new ThreadWait(); t.start(); t.readyLatch.await(); Assert.assertEquals(true, t.waiting); latch.countDown(); t.join(); Assert.assertEquals(false, t.waiting); Assert.assertNull(t.e); Assert.assertTrue(latch.await(1000)); Assert.assertEquals(0, latch.getCount()); latch.countDown(); Assert.assertEquals(0, latch.getCount()); }