예제 #1
0
 /// <exception cref="System.IO.IOException"/>
 internal DfsClientShm(ShortCircuitShm.ShmId shmId, FileInputStream stream, DfsClientShmManager.EndpointShmManager
                       manager, DomainPeer peer)
     : base(shmId, stream)
 {
     this.manager = manager;
     this.peer    = peer;
 }
예제 #2
0
            /// <summary>Pull a slot out of a preexisting shared memory segment.</summary>
            /// <remarks>
            /// Pull a slot out of a preexisting shared memory segment.
            /// Must be called with the manager lock held.
            /// </remarks>
            /// <param name="blockId">The blockId to put inside the Slot object.</param>
            /// <returns>
            /// null if none of our shared memory segments contain a
            /// free slot; the slot object otherwise.
            /// </returns>
            private ShortCircuitShm.Slot AllocSlotFromExistingShm(ExtendedBlockId blockId)
            {
                if (this.notFull.IsEmpty())
                {
                    return(null);
                }
                KeyValuePair <ShortCircuitShm.ShmId, DfsClientShm> entry = this.notFull.FirstEntry
                                                                               ();
                DfsClientShm shm = entry.Value;

                ShortCircuitShm.ShmId shmId = shm.GetShmId();
                ShortCircuitShm.Slot  slot  = shm.AllocAndRegisterSlot(blockId);
                if (shm.IsFull())
                {
                    if (DfsClientShmManager.Log.IsTraceEnabled())
                    {
                        DfsClientShmManager.Log.Trace(this + ": pulled the last slot " + slot.GetSlotIdx(
                                                          ) + " out of " + shm);
                    }
                    DfsClientShm removedShm = Sharpen.Collections.Remove(this.notFull, shmId);
                    Preconditions.CheckState(removedShm == shm);
                    this.full[shmId] = shm;
                }
                else
                {
                    if (DfsClientShmManager.Log.IsTraceEnabled())
                    {
                        DfsClientShmManager.Log.Trace(this + ": pulled slot " + slot.GetSlotIdx() + " out of "
                                                      + shm);
                    }
                }
                return(slot);
            }
예제 #3
0
 /// <summary>Create the ShortCircuitShm.</summary>
 /// <param name="shmId">The ID to use.</param>
 /// <param name="stream">
 /// The stream that we're going to use to create this
 /// shared memory segment.
 /// Although this is a FileInputStream, we are going to
 /// assume that the underlying file descriptor is writable
 /// as well as readable. It would be more appropriate to use
 /// a RandomAccessFile here, but that class does not have
 /// any public accessor which returns a FileDescriptor,
 /// unlike FileInputStream.
 /// </param>
 /// <exception cref="System.IO.IOException"/>
 public ShortCircuitShm(ShortCircuitShm.ShmId shmId, FileInputStream stream)
 {
     if (!NativeIO.IsAvailable())
     {
         throw new NotSupportedException("NativeIO is not available.");
     }
     if (Shell.Windows)
     {
         throw new NotSupportedException("DfsClientShm is not yet implemented for Windows."
                                         );
     }
     if (@unsafe == null)
     {
         throw new NotSupportedException("can't use DfsClientShm because we failed to " +
                                         "load misc.Unsafe.");
     }
     this.shmId         = shmId;
     this.mmappedLength = GetUsableLength(stream);
     this.baseAddress   = NativeIO.POSIX.Mmap(stream.GetFD(), NativeIO.POSIX.MmapProtRead
                                              | NativeIO.POSIX.MmapProtWrite, true, mmappedLength);
     this.slots          = new ShortCircuitShm.Slot[mmappedLength / BytesPerSlot];
     this.allocatedSlots = new BitSet(slots.Length);
     if (Log.IsTraceEnabled())
     {
         Log.Trace("creating " + this.GetType().Name + "(shmId=" + shmId + ", mmappedLength="
                   + mmappedLength + ", baseAddress=" + string.Format("%x", baseAddress) + ", slots.length="
                   + slots.Length + ")");
     }
 }
예제 #4
0
            /// <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;
                    }
                }
            }
예제 #5
0
 /// <summary>Unregister a shared memory segment.</summary>
 /// <remarks>
 /// Unregister a shared memory segment.
 /// Once a segment is unregistered, we will not allocate any more slots
 /// inside that segment.
 /// The DomainSocketWatcher calls this while holding the DomainSocketWatcher
 /// lock.
 /// </remarks>
 /// <param name="shmId">The ID of the shared memory segment to unregister.</param>
 internal virtual void UnregisterShm(ShortCircuitShm.ShmId shmId)
 {
     this._enclosing.Lock.Lock();
     try
     {
         Sharpen.Collections.Remove(this.full, shmId);
         Sharpen.Collections.Remove(this.notFull, shmId);
     }
     finally
     {
         this._enclosing.Lock.Unlock();
     }
 }
예제 #6
0
 public SlotId(ShortCircuitShm.ShmId shmId, int slotIdx)
 {
     this.shmId   = shmId;
     this.slotIdx = slotIdx;
 }