Exemplo n.º 1
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);
     }
 }
Exemplo n.º 2
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();
                    }
                }
            }