예제 #1
0
파일: Selector.cs 프로젝트: fhchina/netmq
        public bool Select(SelectItem[] items, int itemsCount, int timeout)
        {
            if (items == null)
            {
                throw new FaultException();
            }
            if (itemsCount == 0)
            {
                if (timeout == 0)
                {
                    return(false);
                }
                Thread.Sleep(timeout);
                return(false);
            }

            bool firstPass      = true;
            int  numberOfEvents = 0;

            Stopwatch stopwatch = null;

            while (true)
            {
                int currentTimeoutMicroSeconds;

                if (firstPass)
                {
                    currentTimeoutMicroSeconds = 0;
                }
                else if (timeout == -1)
                {
                    currentTimeoutMicroSeconds = -1;
                }
                else
                {
                    currentTimeoutMicroSeconds = (int)((timeout - stopwatch.ElapsedMilliseconds) * 1000);

                    if (currentTimeoutMicroSeconds < 0)
                    {
                        currentTimeoutMicroSeconds = 0;
                    }
                }

                m_checkRead.Clear();
                m_checkWrite.Clear();
                m_checkError.Clear();

                for (int i = 0; i < itemsCount; i++)
                {
                    var pollItem = items[i];

                    if (pollItem.Socket != null)
                    {
                        if (pollItem.Event != PollEvents.None && pollItem.Socket.Handle.Connected)
                        {
                            m_checkRead.Add(pollItem.Socket.Handle);
                        }
                    }
                    else
                    {
                        if ((pollItem.Event & PollEvents.PollIn) == PollEvents.PollIn)
                        {
                            m_checkRead.Add(pollItem.FileDescriptor);
                        }

                        if ((pollItem.Event & PollEvents.PollOut) == PollEvents.PollOut)
                        {
                            m_checkWrite.Add(pollItem.FileDescriptor);
                        }
                    }
                }


                try
                {
                    SocketUtility.Select(m_checkRead, m_checkWrite, m_checkError, currentTimeoutMicroSeconds);
                }
                catch (SocketException)
                {
                    throw new FaultException();
                }

                for (int i = 0; i < itemsCount; i++)
                {
                    var selectItem = items[i];

                    selectItem.ResultEvent = PollEvents.None;

                    if (selectItem.Socket != null)
                    {
                        PollEvents events = (PollEvents)selectItem.Socket.GetSocketOption(ZmqSocketOptions.Events);

                        if ((selectItem.Event & PollEvents.PollIn) == PollEvents.PollIn && (events & PollEvents.PollIn) == PollEvents.PollIn)
                        {
                            selectItem.ResultEvent |= PollEvents.PollIn;
                        }

                        if ((selectItem.Event & PollEvents.PollOut) == PollEvents.PollOut &&
                            (events & PollEvents.PollOut) == PollEvents.PollOut)
                        {
                            selectItem.ResultEvent |= PollEvents.PollOut;
                        }
                    }
                    else
                    {
                        if (m_checkRead.Contains(selectItem.FileDescriptor))
                        {
                            selectItem.ResultEvent |= PollEvents.PollIn;
                        }

                        if (m_checkWrite.Contains(selectItem.FileDescriptor))
                        {
                            selectItem.ResultEvent |= PollEvents.PollOut;
                        }
                    }

                    if (selectItem.ResultEvent != PollEvents.None)
                    {
                        numberOfEvents++;
                    }
                }

                if (timeout == 0)
                {
                    break;
                }

                if (numberOfEvents > 0)
                {
                    break;
                }

                if (timeout < 0)
                {
                    if (firstPass)
                    {
                        firstPass = false;
                    }

                    continue;
                }

                if (firstPass)
                {
                    stopwatch = Stopwatch.StartNew();
                    firstPass = false;
                    continue;
                }

                if (stopwatch.ElapsedMilliseconds > timeout)
                {
                    break;
                }
            }

            return(numberOfEvents > 0);
        }
예제 #2
0
        private void Loop()
        {
            List <Socket> readList  = new List <Socket>();
            List <Socket> writeList = new List <Socket>();
            List <Socket> errorList = new List <Socket>();

            while (!m_stopping)
            {
                m_handles.AddRange(m_addList);
                m_addList.Clear();

                //  Execute any due timers.
                int timeout = ExecuteTimers();

                readList.AddRange(m_checkRead.ToArray());
                writeList.AddRange(m_checkWrite.ToArray());
                errorList.AddRange(m_checkError.ToArray());

                try
                {
                    SocketUtility.Select(readList, writeList, errorList, timeout != 0 ? timeout * 1000 : -1);
                }
                catch (SocketException)
                {
                    continue;
                }

                foreach (var pollSet in m_handles)
                {
                    if (pollSet.Cancelled)
                    {
                        continue;
                    }

                    if (errorList.Contains(pollSet.Socket))
                    {
                        try
                        {
                            pollSet.Handler.InEvent();
                        }
                        catch (TerminatingException)
                        {
                        }
                    }

                    if (pollSet.Cancelled)
                    {
                        continue;
                    }

                    if (writeList.Contains(pollSet.Socket))
                    {
                        try
                        {
                            pollSet.Handler.OutEvent();
                        }
                        catch (TerminatingException)
                        {
                        }
                    }

                    if (pollSet.Cancelled)
                    {
                        continue;
                    }

                    if (readList.Contains(pollSet.Socket))
                    {
                        try
                        {
                            pollSet.Handler.InEvent();
                        }
                        catch (TerminatingException)
                        {
                        }
                    }
                }

                errorList.Clear();
                writeList.Clear();
                readList.Clear();

                if (m_retired)
                {
                    foreach (var item in m_handles.Where(k => k.Cancelled).ToList())
                    {
                        m_handles.Remove(item);
                    }

                    m_retired = false;
                }
            }
        }
예제 #3
0
        /// <summary>
        /// This method is the polling-loop that is invoked on a background thread when Start is called.
        /// As long as Stop hasn't been called: execute the timers, and invoke the handler-methods on each of the saved PollSets.
        /// </summary>
        private void Loop()
        {
            List <Socket> readList  = new List <Socket>();
            List <Socket> writeList = new List <Socket>();
            List <Socket> errorList = new List <Socket>();

            while (!m_stopping)
            {
                // Transfer any sockets from the add-list.
                m_handles.AddRange(m_addList);
                m_addList.Clear();

                // Execute any due timers.
                int timeout = ExecuteTimers();

                readList.AddRange(m_checkRead.ToArray());
                writeList.AddRange(m_checkWrite.ToArray());
                errorList.AddRange(m_checkError.ToArray());

                try
                {
                    SocketUtility.Select(readList, writeList, errorList, timeout != 0 ? timeout * 1000 : -1);
                }
                catch (SocketException)
                {
                    continue;
                }

                // For every PollSet in our list..
                foreach (var pollSet in m_handles)
                {
                    if (pollSet.Cancelled)
                    {
                        continue;
                    }

                    // Invoke its handler's InEvent if it's in our error-list.
                    if (errorList.Contains(pollSet.Socket))
                    {
                        try
                        {
                            pollSet.Handler.InEvent();
                        }
                        catch (TerminatingException)
                        {
                        }
                    }

                    if (pollSet.Cancelled)
                    {
                        continue;
                    }

                    // Invoke its handler's OutEvent if it's in our write-list.
                    if (writeList.Contains(pollSet.Socket))
                    {
                        try
                        {
                            pollSet.Handler.OutEvent();
                        }
                        catch (TerminatingException)
                        {
                        }
                    }

                    if (pollSet.Cancelled)
                    {
                        continue;
                    }

                    // Invoke its handler's InEvent if it's in our read-list.
                    if (readList.Contains(pollSet.Socket))
                    {
                        try
                        {
                            pollSet.Handler.InEvent();
                        }
                        catch (TerminatingException)
                        {
                        }
                    }
                }

                errorList.Clear();
                writeList.Clear();
                readList.Clear();

                if (m_retired)
                {
                    // Take any sockets that have been cancelled out of the list..
                    foreach (var item in m_handles.Where(k => k.Cancelled).ToList())
                    {
                        m_handles.Remove(item);
                    }

                    m_retired = false;
                }
            }
            m_stopped = true;
        }
예제 #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="items">  (must not be null)</param>
        /// <param name="itemsCount"></param>
        /// <param name="timeout">a time-out period, in milliseconds</param>
        /// <returns></returns>
        public bool Select(SelectItem[] items, int itemsCount, int timeout)
        {
            if (items == null)
            {
                throw new FaultException("Selector.Select called with items equal to null.");
            }
            if (itemsCount == 0)
            {
                if (timeout == 0)
                {
                    return(false);
                }
                //TODO:  Do we really want to simply sleep and return, doing nothing during this interval?
                Thread.Sleep(timeout);
                return(false);
            }

            bool firstPass      = true;
            int  numberOfEvents = 0;

            Stopwatch stopwatch = null;

            while (true)
            {
                int currentTimeoutMicroSeconds;

                if (firstPass)
                {
                    currentTimeoutMicroSeconds = 0;
                }
                else if (timeout == -1)
                {
                    currentTimeoutMicroSeconds = -1;
                }
                else
                {
                    currentTimeoutMicroSeconds = (int)((timeout - stopwatch.ElapsedMilliseconds) * 1000);

                    if (currentTimeoutMicroSeconds < 0)
                    {
                        currentTimeoutMicroSeconds = 0;
                    }
                }

                m_checkRead.Clear();
                m_checkWrite.Clear();
                m_checkError.Clear();

                for (int i = 0; i < itemsCount; i++)
                {
                    var pollItem = items[i];

                    if (pollItem.Socket != null)
                    {
                        if (pollItem.Event != PollEvents.None && pollItem.Socket.Handle.Connected)
                        {
                            m_checkRead.Add(pollItem.Socket.Handle);
                        }
                    }
                    else
                    {
                        if ((pollItem.Event & PollEvents.PollIn) == PollEvents.PollIn)
                        {
                            m_checkRead.Add(pollItem.FileDescriptor);
                        }

                        if ((pollItem.Event & PollEvents.PollOut) == PollEvents.PollOut)
                        {
                            m_checkWrite.Add(pollItem.FileDescriptor);
                        }
                    }
                }

                try
                {
                    SocketUtility.Select(m_checkRead, m_checkWrite, m_checkError, currentTimeoutMicroSeconds);
                }
                catch (SocketException x)
                {
#if DEBUG
                    string textOfListRead  = StringLib.AsString(m_checkRead);
                    string textOfListWrite = StringLib.AsString(m_checkWrite);
                    string textOfListError = StringLib.AsString(m_checkError);
                    string xMsg            = String.Format("In Selector.Select, Socket.Select({0}, {1}, {2}, {3}) threw a SocketException: {4}", textOfListRead, textOfListWrite, textOfListError, currentTimeoutMicroSeconds, x.Message);
                    Debug.WriteLine(xMsg);
                    throw new FaultException(innerException: x, message: xMsg);
#else
                    throw new FaultException(innerException: x, message: "Within SocketUtility.Select");
#endif
                }

                for (int i = 0; i < itemsCount; i++)
                {
                    var selectItem = items[i];

                    selectItem.ResultEvent = PollEvents.None;

                    if (selectItem.Socket != null)
                    {
                        PollEvents events = (PollEvents)selectItem.Socket.GetSocketOption(ZmqSocketOptions.Events);

                        if ((selectItem.Event & PollEvents.PollIn) == PollEvents.PollIn && (events & PollEvents.PollIn) == PollEvents.PollIn)
                        {
                            selectItem.ResultEvent |= PollEvents.PollIn;
                        }

                        if ((selectItem.Event & PollEvents.PollOut) == PollEvents.PollOut &&
                            (events & PollEvents.PollOut) == PollEvents.PollOut)
                        {
                            selectItem.ResultEvent |= PollEvents.PollOut;
                        }
                    }
                    else
                    {
                        if (m_checkRead.Contains(selectItem.FileDescriptor))
                        {
                            selectItem.ResultEvent |= PollEvents.PollIn;
                        }

                        if (m_checkWrite.Contains(selectItem.FileDescriptor))
                        {
                            selectItem.ResultEvent |= PollEvents.PollOut;
                        }
                    }

                    if (selectItem.ResultEvent != PollEvents.None)
                    {
                        numberOfEvents++;
                    }
                }

                if (timeout == 0)
                {
                    break;
                }

                if (numberOfEvents > 0)
                {
                    break;
                }

                if (timeout < 0)
                {
                    if (firstPass)
                    {
                        firstPass = false;
                    }

                    continue;
                }

                if (firstPass)
                {
                    stopwatch = Stopwatch.StartNew();
                    firstPass = false;
                    continue;
                }

                if (stopwatch.ElapsedMilliseconds > timeout)
                {
                    break;
                }
            }

            return(numberOfEvents > 0);
        }