protected long await(long nanoSeconds) throws InterruptedException { long target_nano = System.nanoTime() + nanoSeconds; if (!signaled.get()) { // We release the lock at the same time as waiting on the // condition lock.acquired = false; sendAwaitConditionRequest(lock.name, lock.owner); boolean interrupted = false; while (!signaled.get()) { long wait_nano = target_nano - System.nanoTime(); // If we waited max time break out if (wait_nano > 0) { parker.set(Thread.currentThread()); LockSupport.parkNanos(this, wait_nano); if (Thread.interrupted()) { // If we were interrupted and haven't received a response yet then we try to // clean up the lock request and throw the exception if (!signaled.get()) { sendDeleteAwaitConditionRequest(lock.name, lock.owner); throw new InterruptedException(); } // In the case that we were signaled and interrupted // we want to return the signal but still interrupt // our thread interrupted = true; } } else { break; } } if (interrupted) Thread.currentThread().interrupt(); } // We set as if this signal was no released. This way if the // condition is reused again, but the client condition isn't lost // we won't think we were signaled immediately // If we weren't signaled then delete our request if (!signaled.getAndSet(false)) { sendDeleteAwaitConditionRequest(lock.name, lock.owner); } return target_nano - System.nanoTime(); }
@Override public long awaitNanos(long nanosTimeout) throws InterruptedException { long beforeLock; InterruptedException ex = null; try { beforeLock = await(nanosTimeout) + System.nanoTime(); } catch (InterruptedException e) { ex = e; throw ex; } finally { lock.lock(); // If we are throwing an InterruptedException // then clear the interrupt state as well. if (ex != null) { Thread.interrupted(); } } return beforeLock - System.nanoTime(); }
public Responses findMembers( final List<Address> members, final boolean initial_discovery, boolean async) { num_discovery_requests++; int num_expected = members != null ? members.size() : 0; int capacity = members != null ? members.size() : 16; final Responses rsps = new Responses(num_expected, initial_discovery && break_on_coord_rsp, capacity); synchronized (ping_responses) { ping_responses.put(System.nanoTime(), rsps); } if (async || async_discovery) timer.execute(() -> findMembers(members, initial_discovery, rsps)); else findMembers(members, initial_discovery, rsps); weedOutCompletedDiscoveryResponses(); return rsps; }
/** * Removes responses which are done or whose timeout has expired (in the latter case, an expired * response is marked as done) */ @ManagedOperation(description = "Removes expired or completed responses") public void weedOutCompletedDiscoveryResponses() { synchronized (ping_responses) { for (Iterator<Map.Entry<Long, Responses>> it = ping_responses.entrySet().iterator(); it.hasNext(); ) { Map.Entry<Long, Responses> entry = it.next(); long timestamp = entry.getKey(); Responses rsps = entry.getValue(); if (rsps.isDone() || TimeUnit.MILLISECONDS.convert(System.nanoTime() - timestamp, TimeUnit.NANOSECONDS) > discovery_rsp_expiry_time) { it.remove(); rsps.done(); } } } }
protected void addResponse(PingData rsp, boolean overwrite) { synchronized (ping_responses) { for (Iterator<Map.Entry<Long, Responses>> it = ping_responses.entrySet().iterator(); it.hasNext(); ) { Map.Entry<Long, Responses> entry = it.next(); long timestamp = entry.getKey(); Responses rsps = entry.getValue(); rsps.addResponse(rsp, overwrite); if (rsps.isDone() || TimeUnit.MILLISECONDS.convert(System.nanoTime() - timestamp, TimeUnit.NANOSECONDS) > discovery_rsp_expiry_time) { it.remove(); rsps.done(); } } } }