public synchronized void registerSlot(ExtendedBlockId blockId, SlotId slotId, boolean isCached) throws InvalidRequestException { if (!enabled) { if (LOG.isTraceEnabled()) { LOG.trace(this + " can't register a slot because the " + "ShortCircuitRegistry is not enabled."); } throw new UnsupportedOperationException(); } ShmId shmId = slotId.getShmId(); RegisteredShm shm = segments.get(shmId); if (shm == null) { throw new InvalidRequestException("there is no shared memory segment " + "registered with shmId " + shmId); } Slot slot = shm.registerSlot(slotId.getSlotIdx(), blockId); if (isCached) { slot.makeAnchorable(); } else { slot.makeUnanchorable(); } boolean added = slots.put(blockId, slot); Preconditions.checkState(added); if (LOG.isTraceEnabled()) { LOG.trace(this + ": registered " + blockId + " with slot " + slotId + " (isCached=" + isCached + ")"); } }
/** * Invalidate any slot associated with a blockId that we are invalidating * (deleting) from this DataNode. When a slot is invalid, the DFSClient will * not use the corresponding replica for new read or mmap operations (although * existing, ongoing read or mmap operations will complete.) * * @param blockId The block ID. */ public synchronized void processBlockInvalidation(ExtendedBlockId blockId) { if (!enabled) return; final Set<Slot> affectedSlots = slots.get(blockId); if (!affectedSlots.isEmpty()) { final StringBuilder bld = new StringBuilder(); String prefix = ""; bld.append("Block ").append(blockId).append(" has been invalidated. "). append("Marking short-circuit slots as invalid: "); for (Slot slot : affectedSlots) { slot.makeInvalid(); bld.append(prefix).append(slot.toString()); prefix = ", "; } LOG.info(bld.toString()); } }
/** * Try to add a no-checksum anchor to our shared memory slot. * * It is only possible to add this anchor when the block is mlocked on the Datanode. * The DataNode will not munlock the block until the number of no-checksum anchors * for the block reaches zero. * * This method does not require any synchronization. * * @return True if we successfully added a no-checksum anchor. */ public boolean addNoChecksumAnchor() { if (slot == null) { return false; } boolean result = slot.addAnchor(); if (LOG.isTraceEnabled()) { if (result) { LOG.trace(this + ": added no-checksum anchor to slot " + slot); } else { LOG.trace(this + ": could not add no-checksum anchor to slot " + slot); } } return result; }
DfsClientShm shm = (DfsClientShm)slot.getShm(); shm.unregisterSlot(slot.getSlotIdx()); if (shm.isDisconnected()) {
DfsClientShm shm = (DfsClientShm)slot.getShm(); shm.unregisterSlot(slot.getSlotIdx()); if (shm.isDisconnected()) {
DfsClientShm shm = (DfsClientShm)slot.getShm(); shm.unregisterSlot(slot.getSlotIdx()); if (shm.isDisconnected()) {
Assert.assertFalse(slot.addAnchor()); Assert.assertEquals(slotIdx++, slot.getSlotIdx()); slot.makeAnchorable(); Assert.assertTrue(slot.addAnchor()); slot.removeAnchor(); shm.unregisterSlot(slot.getSlotIdx()); slot.makeInvalid();
LOG.trace(ShortCircuitCache.this + ": about to release " + slot); final DfsClientShm shm = (DfsClientShm)slot.getShm(); final DomainSocket shmSock = shm.getPeer().getDomainSocket(); DomainSocket sock = null; out = new DataOutputStream( new BufferedOutputStream(sock.getOutputStream())); new Sender(out).releaseShortCircuitFds(slot.getSlotId()); DataInputStream in = new DataInputStream(sock.getInputStream()); ReleaseShortCircuitAccessResponseProto resp =
LOG.trace(ShortCircuitCache.this + ": about to release " + slot); final DfsClientShm shm = (DfsClientShm)slot.getShm(); final DomainSocket shmSock = shm.getPeer().getDomainSocket(); DomainSocket sock = null; out = new DataOutputStream( new BufferedOutputStream(sock.getOutputStream())); new Sender(out).releaseShortCircuitFds(slot.getSlotId()); DataInputStream in = new DataInputStream(sock.getInputStream()); ReleaseShortCircuitAccessResponseProto resp =
@Override public void run() { LOG.trace("{}: about to release {}", ShortCircuitCache.this, slot); final DfsClientShm shm = (DfsClientShm)slot.getShm(); final DomainSocket shmSock = shm.getPeer().getDomainSocket(); final String path = shmSock.getPath(); DataOutputStream out = new DataOutputStream( new BufferedOutputStream(sock.getOutputStream()))) { new Sender(out).releaseShortCircuitFds(slot.getSlotId()); DataInputStream in = new DataInputStream(sock.getInputStream()); ReleaseShortCircuitAccessResponseProto resp =
Assert.assertFalse(slot.addAnchor()); Assert.assertEquals(slotIdx++, slot.getSlotIdx()); slot.makeAnchorable(); Assert.assertTrue(slot.addAnchor()); slot.removeAnchor(); shm.unregisterSlot(slot.getSlotIdx()); slot.makeInvalid();
if (shm.isFull()) { if (LOG.isTraceEnabled()) { LOG.trace(this + ": pulled the last slot " + slot.getSlotIdx() + " out of " + shm); } else { if (LOG.isTraceEnabled()) { LOG.trace(this + ": pulled slot " + slot.getSlotIdx() + " out of " + shm);
boolean stale = !slot.isValid(); if (LOG.isTraceEnabled()) { LOG.trace(this + ": checked shared memory segment. isStale=" + stale);
boolean stale = !slot.isValid(); if (LOG.isTraceEnabled()) { LOG.trace(this + ": checked shared memory segment. isStale=" + stale);
if (shm.isFull()) { if (LOG.isTraceEnabled()) { LOG.trace(this + ": pulled the last slot " + slot.getSlotIdx() + " out of " + shm); } else { if (LOG.isTraceEnabled()) { LOG.trace(this + ": pulled slot " + slot.getSlotIdx() + " out of " + shm);
/** * Pull a slot out of a preexisting shared memory segment. * * Must be called with the manager lock held. * * @param blockId The blockId to put inside the Slot object. * * @return null if none of our shared memory segments contain a * free slot; the slot object otherwise. */ private Slot allocSlotFromExistingShm(ExtendedBlockId blockId) { if (notFull.isEmpty()) { return null; } Entry<ShmId, DfsClientShm> entry = notFull.firstEntry(); DfsClientShm shm = entry.getValue(); ShmId shmId = shm.getShmId(); Slot slot = shm.allocAndRegisterSlot(blockId); if (shm.isFull()) { LOG.trace("{}: pulled the last slot {} out of {}", this, slot.getSlotIdx(), shm); DfsClientShm removedShm = notFull.remove(shmId); Preconditions.checkState(removedShm == shm); full.put(shmId, shm); } else { LOG.trace("{}: pulled slot {} out of {}", this, slot.getSlotIdx(), shm); } return slot; }
/** * Handle the closure of the UNIX domain socket associated with this shared * memory segment by marking this segment as stale. * * If there are no slots associated with this shared memory segment, it will * be freed immediately in this function. */ @Override public boolean handle(DomainSocket sock) { manager.unregisterShm(getShmId()); synchronized (this) { Preconditions.checkState(!disconnected); disconnected = true; boolean hadSlots = false; for (Iterator<Slot> iter = slotIterator(); iter.hasNext(); ) { Slot slot = iter.next(); slot.makeInvalid(); hadSlots = true; } if (!hadSlots) { free(); } } return true; } }