/// <summary>Stop tracking a slot.</summary> /// <remarks> /// Stop tracking a slot. /// Must be called with the EndpointShmManager lock held. /// </remarks> /// <param name="slot">The slot to release.</param> internal virtual void FreeSlot(ShortCircuitShm.Slot slot) { DfsClientShm shm = (DfsClientShm)slot.GetShm(); shm.UnregisterSlot(slot.GetSlotIdx()); if (shm.IsDisconnected()) { // Stale shared memory segments should not be tracked here. Preconditions.CheckState(!this.full.Contains(shm.GetShmId())); Preconditions.CheckState(!this.notFull.Contains(shm.GetShmId())); if (shm.IsEmpty()) { if (DfsClientShmManager.Log.IsTraceEnabled()) { DfsClientShmManager.Log.Trace(this + ": freeing empty stale " + shm); } shm.Free(); } } else { ShortCircuitShm.ShmId shmId = shm.GetShmId(); Sharpen.Collections.Remove(this.full, shmId); // The shm can't be full if we just freed a slot. if (shm.IsEmpty()) { Sharpen.Collections.Remove(this.notFull, shmId); // If the shared memory segment is now empty, we call shutdown(2) on // the UNIX domain socket associated with it. The DomainSocketWatcher, // which is watching this socket, will call DfsClientShm#handle, // cleaning up this shared memory segment. // // See #{DfsClientShmManager#domainSocketWatcher} for details about why // we don't want to call DomainSocketWatcher#remove directly here. // // Note that we could experience 'fragmentation' here, where the // DFSClient allocates a bunch of slots in different shared memory // segments, and then frees most of them, but never fully empties out // any segment. We make some attempt to avoid this fragmentation by // always allocating new slots out of the shared memory segment with the // lowest ID, but it could still occur. In most workloads, // fragmentation should not be a major concern, since it doesn't impact // peak file descriptor usage or the speed of allocation. if (DfsClientShmManager.Log.IsTraceEnabled()) { DfsClientShmManager.Log.Trace(this + ": shutting down UNIX domain socket for " + "empty " + shm); } this.Shutdown(shm); } else { this.notFull[shmId] = shm; } } }
/// <exception cref="System.IO.IOException"/> public void Visit(Dictionary <DatanodeInfo, DfsClientShmManager.PerDatanodeVisitorInfo > info) { NUnit.Framework.Assert.IsTrue(info[datanode].full.IsEmpty()); NUnit.Framework.Assert.IsFalse(info[datanode].disabled); NUnit.Framework.Assert.AreEqual(1, info[datanode].notFull.Values.Count); DfsClientShm shm = info[datanode].notFull.Values.GetEnumerator().Next(); NUnit.Framework.Assert.IsFalse(shm.IsDisconnected()); }