Example #1
0
		public  int doOneEvent(int flags)
		// Miscellaneous flag values: may be any
		// combination of TCL.DONT_WAIT,
		// TCL.WINDOW_EVENTS, TCL.FILE_EVENTS,
		// TCL.TIMER_EVENTS, TCL.IDLE_EVENTS,
		// or others defined by event sources.
		{
			int result = 0;
			
			// No event flags is equivalent to TCL_ALL_EVENTS.
			
			if ((flags & TCL.ALL_EVENTS) == 0)
			{
				flags |= TCL.ALL_EVENTS;
			}
			
			// The core of this procedure is an infinite loop, even though
			// we only service one event.  The reason for this is that we
			// may be processing events that don't do anything inside of Tcl.
			
			while (true)
			{
				// If idle events are the only things to service, skip the
				// main part of the loop and go directly to handle idle
				// events (i.e. don't wait even if TCL_DONT_WAIT isn't set).
				
				if ((flags & TCL.ALL_EVENTS) == TCL.IDLE_EVENTS)
				{
					return serviceIdle();
				}
				
				long sysTime = (System.DateTime.Now.Ticks - 621355968000000000) / 10000;
				
				// If some timers have been expired, queue them into the
				// event queue. We can't process expired times right away,
				// because there may already be other events on the queue.
				
				if (!timerPending && (timerList.Count > 0))
				{
					TimerHandler h = (TimerHandler) timerList[0];
					
					if (h.atTime <= sysTime)
					{
						TimerEvent Tevent = new TimerEvent();
						Tevent.notifier = this;
            queueEvent( Tevent, TCL.QUEUE_TAIL );
						timerPending = true;
					}
				}
				
				// Service a queued event, if there are any.
				
				if (serviceEvent(flags) != 0)
				{
					result = 1;
					break;
				}
				
				// There is no event on the queue. Check for idle events.
				
				if ((flags & TCL.IDLE_EVENTS) != 0)
				{
					if (serviceIdle() != 0)
					{
						result = 1;
						break;
					}
				}
				
				if ((flags & TCL.DONT_WAIT) != 0)
				{
					break;
				}
				
				// We don't have any event to service. We'll wait if
				// TCL.DONT_WAIT. When the following wait() call returns,
				// one of the following things may happen:
				//
				// (1) waitTime milliseconds has elasped (if waitTime != 0);
				//
				// (2) The primary notifier has been notify()'ed by other threads:
				//     (a) an event is queued by queueEvent().
				//     (b) a timer handler was created by new TimerHandler();
				//     (c) an idle handler was created by new IdleHandler();
				// (3) We receive an InterruptedException.
				//
				
				try
				{
					// Don't acquire the monitor until we are about to wait
					// for notification from another thread. It is critical
					// that this entire method not be synchronized since
					// a call to processEvent via serviceEvent could take
					// a very long time. We don't want the monitor held
					// during that time since that would force calls to
					// queueEvent in other threads to wait.
					
					lock (this)
					{
						if (timerList.Count > 0)
						{
							TimerHandler h = (TimerHandler) timerList[0];
							long waitTime = h.atTime - sysTime;
							if (waitTime > 0)
							{
								System.Threading.Monitor.Wait(this, TimeSpan.FromMilliseconds(waitTime));
							}
						}
						else
						{
							System.Threading.Monitor.Wait(this);
						}
					} // synchronized (this)
				}
				catch (System.Threading.ThreadInterruptedException e)
				{
					// We ignore any InterruptedException and loop continuously
					// until we receive an event.
				}
			}
			
			return result;
		}
Example #2
0
        public int doOneEvent(int flags)
        // Miscellaneous flag values: may be any
        // combination of TCL.DONT_WAIT,
        // TCL.WINDOW_EVENTS, TCL.FILE_EVENTS,
        // TCL.TIMER_EVENTS, TCL.IDLE_EVENTS,
        // or others defined by event sources.
        {
            int result = 0;

            // No event flags is equivalent to TCL_ALL_EVENTS.

            if ((flags & TCL.ALL_EVENTS) == 0)
            {
                flags |= TCL.ALL_EVENTS;
            }

            // The core of this procedure is an infinite loop, even though
            // we only service one event.  The reason for this is that we
            // may be processing events that don't do anything inside of Tcl.

            while (true)
            {
                // If idle events are the only things to service, skip the
                // main part of the loop and go directly to handle idle
                // events (i.e. don't wait even if TCL_DONT_WAIT isn't set).

                if ((flags & TCL.ALL_EVENTS) == TCL.IDLE_EVENTS)
                {
                    return(serviceIdle());
                }

                long sysTime = (System.DateTime.Now.Ticks - 621355968000000000) / 10000;

                // If some timers have been expired, queue them into the
                // event queue. We can't process expired times right away,
                // because there may already be other events on the queue.

                if (!timerPending && (timerList.Count > 0))
                {
                    TimerHandler h = (TimerHandler)timerList[0];

                    if (h.atTime <= sysTime)
                    {
                        TimerEvent Tevent = new TimerEvent();
                        Tevent.notifier = this;
                        queueEvent(Tevent, TCL.QUEUE_TAIL);
                        timerPending = true;
                    }
                }

                // Service a queued event, if there are any.

                if (serviceEvent(flags) != 0)
                {
                    result = 1;
                    break;
                }

                // There is no event on the queue. Check for idle events.

                if ((flags & TCL.IDLE_EVENTS) != 0)
                {
                    if (serviceIdle() != 0)
                    {
                        result = 1;
                        break;
                    }
                }

                if ((flags & TCL.DONT_WAIT) != 0)
                {
                    break;
                }

                // We don't have any event to service. We'll wait if
                // TCL.DONT_WAIT. When the following wait() call returns,
                // one of the following things may happen:
                //
                // (1) waitTime milliseconds has elasped (if waitTime != 0);
                //
                // (2) The primary notifier has been notify()'ed by other threads:
                //     (a) an event is queued by queueEvent().
                //     (b) a timer handler was created by new TimerHandler();
                //     (c) an idle handler was created by new IdleHandler();
                // (3) We receive an InterruptedException.
                //

                try
                {
                    // Don't acquire the monitor until we are about to wait
                    // for notification from another thread. It is critical
                    // that this entire method not be synchronized since
                    // a call to processEvent via serviceEvent could take
                    // a very long time. We don't want the monitor held
                    // during that time since that would force calls to
                    // queueEvent in other threads to wait.

                    lock (this)
                    {
                        if (timerList.Count > 0)
                        {
                            TimerHandler h        = (TimerHandler)timerList[0];
                            long         waitTime = h.atTime - sysTime;
                            if (waitTime > 0)
                            {
                                System.Threading.Monitor.Wait(this, TimeSpan.FromMilliseconds(waitTime));
                            }
                        }
                        else
                        {
                            System.Threading.Monitor.Wait(this);
                        }
                    } // synchronized (this)
                }
                catch (System.Threading.ThreadInterruptedException e)
                {
                    // We ignore any InterruptedException and loop continuously
                    // until we receive an event.
                }
            }

            return(result);
        }