예제 #1
0
        /// <summary>
        /// Send callback and return whether or not the domain socket was closed as a
        /// result of processing.
        /// </summary>
        /// <param name="caller">reason for call</param>
        /// <param name="entries">mapping of file descriptor to entry</param>
        /// <param name="fdSet">set of file descriptors</param>
        /// <param name="fd">file descriptor</param>
        /// <returns>true if the domain socket was closed as a result of processing</returns>
        private bool SendCallback(string caller, SortedDictionary <int, DomainSocketWatcher.Entry
                                                                   > entries, DomainSocketWatcher.FdSet fdSet, int fd)
        {
            if (Log.IsTraceEnabled())
            {
                Log.Trace(this + ": " + caller + " starting sendCallback for fd " + fd);
            }
            DomainSocketWatcher.Entry entry = entries[fd];
            Preconditions.CheckNotNull(entry, this + ": fdSet contained " + fd + ", which we were "
                                       + "not tracking.");
            DomainSocket sock = entry.GetDomainSocket();

            if (entry.GetHandler().Handle(sock))
            {
                if (Log.IsTraceEnabled())
                {
                    Log.Trace(this + ": " + caller + ": closing fd " + fd + " at the request of the handler."
                              );
                }
                if (Collections.Remove(toRemove, fd) != null)
                {
                    if (Log.IsTraceEnabled())
                    {
                        Log.Trace(this + ": " + caller + " : sendCallback processed fd " + fd + " in toRemove."
                                  );
                    }
                }
                try
                {
                    sock.refCount.UnreferenceCheckClosed();
                }
                catch (IOException)
                {
                    Preconditions.CheckArgument(false, this + ": file descriptor " + sock.fd + " was closed while "
                                                + "still in the poll(2) loop.");
                }
                IOUtils.Cleanup(Log, sock);
                fdSet.Remove(fd);
                return(true);
            }
            else
            {
                if (Log.IsTraceEnabled())
                {
                    Log.Trace(this + ": " + caller + ": sendCallback not " + "closing fd " + fd);
                }
                return(false);
            }
        }
예제 #2
0
 private void AddNotificationSocket(SortedDictionary <int, DomainSocketWatcher.Entry
                                                      > entries, DomainSocketWatcher.FdSet fdSet)
 {
     entries[notificationSockets[1].fd] = new DomainSocketWatcher.Entry(notificationSockets
                                                                        [1], new DomainSocketWatcher.NotificationHandler(this));
     try
     {
         notificationSockets[1].refCount.Reference();
     }
     catch (IOException e)
     {
         throw new RuntimeException(e);
     }
     fdSet.Add(notificationSockets[1].fd);
     if (Log.IsTraceEnabled())
     {
         Log.Trace(this + ": adding notificationSocket " + notificationSockets[1].fd + ", connected to "
                   + notificationSockets[0].fd);
     }
 }
예제 #3
0
 /// <exception cref="System.IO.IOException"/>
 private static int DoPoll0(int maxWaitMs, DomainSocketWatcher.FdSet readFds)
 {
 }
예제 #4
0
            public void Run()
            {
                if (DomainSocketWatcher.Log.IsDebugEnabled())
                {
                    DomainSocketWatcher.Log.Debug(this + ": starting with interruptCheckPeriodMs = "
                                                  + this._enclosing.interruptCheckPeriodMs);
                }
                SortedDictionary <int, DomainSocketWatcher.Entry> entries = new SortedDictionary <int
                                                                                                  , DomainSocketWatcher.Entry>();

                DomainSocketWatcher.FdSet fdSet = new DomainSocketWatcher.FdSet();
                this._enclosing.AddNotificationSocket(entries, fdSet);
                try
                {
                    while (true)
                    {
                        this._enclosing.Lock.Lock();
                        try
                        {
                            foreach (int fd in fdSet.GetAndClearReadableFds())
                            {
                                this._enclosing.SendCallbackAndRemove("getAndClearReadableFds", entries, fdSet, fd
                                                                      );
                            }
                            if (!(this._enclosing.toAdd.IsEmpty() && this._enclosing.toRemove.IsEmpty()))
                            {
                                // Handle pending additions (before pending removes).
                                for (IEnumerator <DomainSocketWatcher.Entry> iter = this._enclosing.toAdd.GetEnumerator
                                                                                        (); iter.HasNext();)
                                {
                                    DomainSocketWatcher.Entry entry = iter.Next();
                                    DomainSocket sock = entry.GetDomainSocket();
                                    DomainSocketWatcher.Entry prevEntry = entries[sock.fd] = entry;
                                    Preconditions.CheckState(prevEntry == null, this + ": tried to watch a file descriptor that we "
                                                             + "were already watching: " + sock);
                                    if (DomainSocketWatcher.Log.IsTraceEnabled())
                                    {
                                        DomainSocketWatcher.Log.Trace(this + ": adding fd " + sock.fd);
                                    }
                                    fdSet.Add(sock.fd);
                                    iter.Remove();
                                }
                                // Handle pending removals
                                while (true)
                                {
                                    KeyValuePair <int, DomainSocket> entry = this._enclosing.toRemove.FirstEntry();
                                    if (entry == null)
                                    {
                                        break;
                                    }
                                    this._enclosing.SendCallbackAndRemove("handlePendingRemovals", entries, fdSet, entry
                                                                          .Value.fd);
                                }
                                this._enclosing.processedCond.SignalAll();
                            }
                            // Check if the thread should terminate.  Doing this check now is
                            // easier than at the beginning of the loop, since we know toAdd and
                            // toRemove are now empty and processedCond has been notified if it
                            // needed to be.
                            if (this._enclosing.closed)
                            {
                                if (DomainSocketWatcher.Log.IsDebugEnabled())
                                {
                                    DomainSocketWatcher.Log.Debug(this.ToString() + " thread terminating.");
                                }
                                return;
                            }
                            // Check if someone sent our thread an InterruptedException while we
                            // were waiting in poll().
                            if (Thread.Interrupted())
                            {
                                throw new Exception();
                            }
                        }
                        finally
                        {
                            this._enclosing.Lock.Unlock();
                        }
                        DomainSocketWatcher.DoPoll0(this._enclosing.interruptCheckPeriodMs, fdSet);
                    }
                }
                catch (Exception)
                {
                    DomainSocketWatcher.Log.Info(this.ToString() + " terminating on InterruptedException"
                                                 );
                }
                catch (Exception e)
                {
                    DomainSocketWatcher.Log.Error(this.ToString() + " terminating on exception", e);
                }
                finally
                {
                    this._enclosing.Lock.Lock();
                    try
                    {
                        this._enclosing.Kick();
                        // allow the handler for notificationSockets[0] to read a byte
                        foreach (DomainSocketWatcher.Entry entry in entries.Values)
                        {
                            // We do not remove from entries as we iterate, because that can
                            // cause a ConcurrentModificationException.
                            this._enclosing.SendCallback("close", entries, fdSet, entry.GetDomainSocket().fd);
                        }
                        entries.Clear();
                        fdSet.Close();
                    }
                    finally
                    {
                        this._enclosing.Lock.Unlock();
                    }
                }
            }
예제 #5
0
 /// <summary>
 /// Send callback, and if the domain socket was closed as a result of
 /// processing, then also remove the entry for the file descriptor.
 /// </summary>
 /// <param name="caller">reason for call</param>
 /// <param name="entries">mapping of file descriptor to entry</param>
 /// <param name="fdSet">set of file descriptors</param>
 /// <param name="fd">file descriptor</param>
 private void SendCallbackAndRemove(string caller, SortedDictionary <int, DomainSocketWatcher.Entry
                                                                     > entries, DomainSocketWatcher.FdSet fdSet, int fd)
 {
     if (SendCallback(caller, entries, fdSet, fd))
     {
         Collections.Remove(entries, fd);
     }
 }