public IdleHandler( Notifier n )
    {
      notifier = (Notifier)n;
      isCancelled = false;

      lock ( notifier )
      {
        notifier.idleList.Add( this );
        generation = notifier.idleGeneration;
        if ( System.Threading.Thread.CurrentThread != notifier.primaryThread )
        {
          System.Threading.Monitor.PulseAll( notifier );
        }
      }
    }
    public TimerHandler( Notifier n, int milliseconds )
    {
      int i;

      atTime = ( System.DateTime.Now.Ticks - 621355968000000000 ) / 10000 + milliseconds;
      notifier = (Notifier)n;
      isCancelled = false;

      /*
      * Add the event to the queue in the correct position (ordered by
      * event firing time).
      *
      * NOTE: it's very important that if two timer handlers have the
      * same atTime, the newer timer handler always goes after the
      * older handler in the list. See comments in
      * Notifier.TimerEvent.processEvent() for details.
      */

      lock ( notifier )
      {
        generation = notifier.timerGeneration;

        for ( i = 0; i < notifier.timerList.Count; i++ )
        {
          TimerHandler q = (TimerHandler)notifier.timerList[i];
          if ( atTime < q.atTime )
          {
            break;
          }
        }
        notifier.timerList.Insert( i, this );

        if ( System.Threading.Thread.CurrentThread != notifier.primaryThread )
        {
          System.Threading.Monitor.PulseAll( notifier );
        }
      }
    }
Exemple #3
0
				public static Notifier getNotifierForThread(System.Threading.Thread thread)
		// The thread that owns this Notifier.
		{
			lock (typeof(tcl.lang.Notifier))
			{
				Notifier notifier = (Notifier) notifierTable[thread];
				if (notifier == null)
				{
					notifier = new Notifier(thread);
					SupportClass.PutElement(notifierTable, thread, notifier);
				}
				
				return notifier;
			}
		}
 internal BgError( BgErrorMgr enclosingInstance, Notifier n )
   : base( n )
 {
   InitBlock( enclosingInstance );
 }
Exemple #5
0
 internal TimerInfo( AfterCmd enclosingInstance, Notifier n, int milliseconds )
     : base(n, milliseconds)
 {
     InitBlock( enclosingInstance );
 }
Exemple #6
0
 internal IdleInfo( AfterCmd enclosingInstance, Notifier n )
     : base(n)
 {
     InitBlock( enclosingInstance );
 }
    public override void eventuallyDispose()
    {
      if ( deleted )
      {
        return;
      }

      deleted = true;

      if ( nestLevel > 0 )
      {
        //-- TODO -- Determine why this is an error             throw new TclRuntimeError("dispose() called with active evals");
      }

      // Remove our association with the notifer (if we had one).

      if ( notifier != null )
      {
        notifier.release();
        notifier = null;
      }

      // Dismantle everything in the global namespace except for the
      // "errorInfo" and "errorCode" variables. These might be needed
      // later on if errors occur while deleting commands. We are careful
      // to destroy and recreate the "errorInfo" and "errorCode"
      // variables, in case they had any traces on them.
      //
      // Dismantle the namespace here, before we clear the assocData. If any
      // background errors occur here, they will be deleted below.


      // FIXME : check impl of TclTeardownNamespace
      NamespaceCmd.teardownNamespace( globalNs );

      // Delete all variables.

      TclObject errorInfoObj = null, errorCodeObj = null;

      try
      {
        errorInfoObj = getVar( "errorInfo", null, TCL.VarFlag.GLOBAL_ONLY );
      }
      catch ( TclException e )
      {
        // Do nothing when var does not exist.
      }

      if ( errorInfoObj != null )
      {
        errorInfoObj.preserve();
      }

      try
      {
        errorCodeObj = getVar( "errorCode", null, TCL.VarFlag.GLOBAL_ONLY );
      }
      catch ( TclException e )
      {
        // Do nothing when var does not exist.
      }

      if ( errorCodeObj != null )
      {
        errorCodeObj.preserve();
      }

      frame = null;
      varFrame = null;

      try
      {
        if ( errorInfoObj != null )
        {
          setVar( "errorInfo", null, errorInfoObj, TCL.VarFlag.GLOBAL_ONLY );
          errorInfoObj.release();
        }
        if ( errorCodeObj != null )
        {
          setVar( "errorCode", null, errorCodeObj, TCL.VarFlag.GLOBAL_ONLY );
          errorCodeObj.release();
        }
      }
      catch ( TclException e )
      {
        // Ignore it -- same behavior as Tcl 8.0.
      }

      // Tear down the math function table.

      expr = null;

      // Remove all the assoc data tied to this interp and invoke
      // deletion callbacks; note that a callback can create new
      // callbacks, so we iterate.

      // ATK The java code was somethink strong
      if ( assocData != null )
      {
        foreach ( AssocData data in assocData.Values )
        {
          data.disposeAssocData( this );
        }
        assocData.Clear();
      }

      // Close any remaining channels

      for ( IDictionaryEnumerator e = interpChanTable.GetEnumerator(); e.MoveNext(); )
      {
        Object key = e.Key;
        Channel chan = (Channel)e.Value;
        try
        {
          chan.close();
        }
        catch ( IOException ex )
        {
          // Ignore any IO errors
        }
      }

      // Finish deleting the global namespace.

      // FIXME : check impl of Tcl_DeleteNamespace
      NamespaceCmd.deleteNamespace( globalNs );
      globalNs = null;

      // Free up the result *after* deleting variables, since variable
      // deletion could have transferred ownership of the result string
      // to Tcl.

      frame = null;
      varFrame = null;
      resolvers = null;

      resetResult();
    }
    public Interp()
    {
      InitBlock();

      //freeProc         = null;
      errorLine = 0;

      // An empty result is used pretty often. We will use a shared
      // TclObject instance to represent the empty result so that we
      // don't need to create a new TclObject instance every time the
      // interpreter result is set to empty.

      m_nullResult = TclString.newInstance( "" );
      m_nullResult.preserve(); // Increment refCount to 1
      m_nullResult.preserve(); // Increment refCount to 2 (shared)
      m_result = TclString.newInstance( "" ); //m_nullResult; // correcponds to iPtr->objResultPtr
      m_result.preserve();

      expr = new Expression();
      nestLevel = 0;
      maxNestingDepth = 1000;

      frame = null;
      varFrame = null;

      returnCode = TCL.CompletionCode.OK;
      errorInfo = null;
      errorCode = null;

      packageTable = new Hashtable();
      packageUnknown = null;
      cmdCount = 0;
      termOffset = 0;
      resolvers = null;
      evalFlags = 0;
      scriptFile = null;
      flags = 0;
      isSafe = false;
      assocData = null;


      globalNs = null; // force creation of global ns below
      globalNs = NamespaceCmd.createNamespace( this, null, null );
      if ( globalNs == null )
      {
        throw new TclRuntimeError( "Interp(): can't create global namespace" );
      }


      // Init things that are specific to the Jacl implementation

      workingDir = new FileInfo( System.Environment.CurrentDirectory );
      noEval = 0;

      notifier = Notifier.getNotifierForThread( System.Threading.Thread.CurrentThread );
      notifier.preserve();

      randSeedInit = false;

      deleted = false;
      errInProgress = false;
      errAlreadyLogged = false;
      errCodeSet = false;

      dbg = initDebugInfo();

      slaveTable = new Hashtable();
      targetTable = new Hashtable();
      aliasTable = new Hashtable();

      // init parser variables
      Parser.init( this );
      TclParse.init( this );

      // Initialize the Global (static) channel table and the local
      // interp channel table.

      interpChanTable = TclIO.getInterpChanTable( this );

      // Sets up the variable trace for tcl_precision.

      Util.setupPrecisionTrace( this );

      // Create the built-in commands.

      createCommands();

      try
      {
        // Set up tcl_platform, tcl_version, tcl_library and other
        // global variables.

        setVar( "tcl_platform", "platform", "windows", TCL.VarFlag.GLOBAL_ONLY );
        setVar( "tcl_platform", "byteOrder", "bigEndian", TCL.VarFlag.GLOBAL_ONLY );

        setVar( "tcl_platform", "os", Environment.OSVersion.Platform.ToString(), TCL.VarFlag.GLOBAL_ONLY );
        setVar( "tcl_platform", "osVersion", Environment.OSVersion.Version.ToString(), TCL.VarFlag.GLOBAL_ONLY );
        setVar( "tcl_platform", "machine", Util.tryGetSystemProperty( "os.arch", "?" ), TCL.VarFlag.GLOBAL_ONLY );

        setVar( "tcl_version", TCL_VERSION, TCL.VarFlag.GLOBAL_ONLY );
        setVar( "tcl_patchLevel", TCL_PATCH_LEVEL, TCL.VarFlag.GLOBAL_ONLY );
        setVar( "tcl_library", "resource:/tcl/lang/library", TCL.VarFlag.GLOBAL_ONLY );
        if ( Util.Windows )
        {
          setVar( "tcl_platform", "host_platform", "windows", TCL.VarFlag.GLOBAL_ONLY );
        }
        else if ( Util.Mac )
        {
          setVar( "tcl_platform", "host_platform", "macintosh", TCL.VarFlag.GLOBAL_ONLY );
        }
        else
        {
          setVar( "tcl_platform", "host_platform", "unix", TCL.VarFlag.GLOBAL_ONLY );
        }

        // Create the env array an populated it with proper
        // values.

        Env.initialize( this );

        // Register Tcl's version number. Note: This MUST be 
        // done before the call to evalResource, otherwise
        // calls to "package require tcl" will fail.

        pkgProvide( "Tcl", TCL_VERSION );

        // Source the init.tcl script to initialize auto-loading.

        evalResource( "/tcl/lang/library/init.tcl" );
      }
      catch ( TclException e )
      {
        System.Diagnostics.Debug.WriteLine( getResult().ToString() );
        SupportClass.WriteStackTrace( e, Console.Error );
        throw new TclRuntimeError( "unexpected TclException: " + e.Message, e );
      }
    }
Exemple #9
0
 internal IdleInfo(AfterCmd enclosingInstance, Notifier n)
     : base(n)
 {
     InitBlock(enclosingInstance);
 }
Exemple #10
0
        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
        {
            int      i;
            Notifier notifier = (Notifier)interp.getNotifier();
            Object   info;

            if (assocData == null)
            {
                /*
                 * Create the "after" information associated for this
                 * interpreter, if it doesn't already exist.
                 */

                assocData = (AfterAssocData)interp.getAssocData("tclAfter");
                if (assocData == null)
                {
                    assocData = new AfterAssocData(this);
                    interp.setAssocData("tclAfter", assocData);
                }
            }

            if (argv.Length < 2)
            {
                throw new TclNumArgsException(interp, 1, argv, "option ?arg arg ...?");
            }

            /*
             * First lets see if the command was passed a number as the first argument.
             */

            bool isNumber = false;
            int  ms       = 0;

            if (argv[1].InternalRep is TclInteger)
            {
                ms       = TclInteger.get(interp, argv[1]);
                isNumber = true;
            }
            else
            {
                string s = argv[1].ToString();
                if ((s.Length > 0) && (System.Char.IsDigit(s[0])))
                {
                    ms       = TclInteger.get(interp, argv[1]);
                    isNumber = true;
                }
            }

            if (isNumber)
            {
                if (ms < 0)
                {
                    ms = 0;
                }
                if (argv.Length == 2)
                {
                    /*
                     * Sleep for at least the given milliseconds and return.
                     */

                    long endTime = System.DateTime.Now.Ticks / 10000 + ms;
                    while (true)
                    {
                        try
                        {
                            System.Threading.Thread.Sleep(ms);
                            return(TCL.CompletionCode.RETURN);
                        }
                        catch (System.Threading.ThreadInterruptedException e)
                        {
                            /*
                             * We got interrupted. Sleep again if we havn't slept
                             * long enough yet.
                             */

                            long sysTime = System.DateTime.Now.Ticks / 10000;
                            if (sysTime >= endTime)
                            {
                                return(TCL.CompletionCode.RETURN);
                            }
                            ms = (int)(endTime - sysTime);
                            continue;
                        }
                    }
                }

                TclObject cmd = getCmdObject(argv);
                cmd.preserve();

                assocData.lastAfterId++;
                TimerInfo timerInfo = new TimerInfo(this, notifier, ms);
                timerInfo.interp  = interp;
                timerInfo.command = cmd;
                timerInfo.id      = assocData.lastAfterId;

                assocData.handlers.Add(timerInfo);

                interp.setResult("after#" + timerInfo.id);

                return(TCL.CompletionCode.RETURN);
            }

            /*
             * If it's not a number it must be a subcommand.
             */

            int index;

            try
            {
                index = TclIndex.get(interp, argv[1], validOpts, "option", 0);
            }
            catch (TclException e)
            {
                throw new TclException(interp, "bad argument \"" + argv[1] + "\": must be cancel, idle, info, or a number");
            }

            switch (index)
            {
            case OPT_CANCEL:
                if (argv.Length < 3)
                {
                    throw new TclNumArgsException(interp, 2, argv, "id|command");
                }

                TclObject arg = getCmdObject(argv);
                arg.preserve();

                /*
                 * Search the timer/idle handler by id or by command.
                 */

                info = null;
                for (i = 0; i < assocData.handlers.Count; i++)
                {
                    Object obj = assocData.handlers[i];
                    if (obj is TimerInfo)
                    {
                        TclObject cmd = ((TimerInfo)obj).command;

                        if ((cmd == arg) || cmd.ToString().Equals(arg.ToString()))
                        {
                            info = obj;
                            break;
                        }
                    }
                    else
                    {
                        TclObject cmd = ((IdleInfo)obj).command;

                        if ((cmd == arg) || cmd.ToString().Equals(arg.ToString()))
                        {
                            info = obj;
                            break;
                        }
                    }
                }
                if (info == null)
                {
                    info = getAfterEvent(arg.ToString());
                }
                arg.release();

                /*
                 * Cancel the handler.
                 */

                if (info != null)
                {
                    if (info is TimerInfo)
                    {
                        ((TimerInfo)info).cancel();
                        ((TimerInfo)info).command.release();
                    }
                    else
                    {
                        ((IdleInfo)info).cancel();
                        ((IdleInfo)info).command.release();
                    }

                    SupportClass.VectorRemoveElement(assocData.handlers, info);
                }
                break;


            case OPT_IDLE:
                if (argv.Length < 3)
                {
                    throw new TclNumArgsException(interp, 2, argv, "script script ...");
                }

                TclObject cmd2 = getCmdObject(argv);
                cmd2.preserve();
                assocData.lastAfterId++;

                IdleInfo idleInfo = new IdleInfo(this, notifier);
                idleInfo.interp  = interp;
                idleInfo.command = cmd2;
                idleInfo.id      = assocData.lastAfterId;

                assocData.handlers.Add(idleInfo);

                interp.setResult("after#" + idleInfo.id);
                break;


            case OPT_INFO:
                if (argv.Length == 2)
                {
                    /*
                     * No id is given. Return a list of current after id's.
                     */

                    TclObject list = TclList.newInstance();
                    for (i = 0; i < assocData.handlers.Count; i++)
                    {
                        int    id;
                        Object obj = assocData.handlers[i];
                        if (obj is TimerInfo)
                        {
                            id = ((TimerInfo)obj).id;
                        }
                        else
                        {
                            id = ((IdleInfo)obj).id;
                        }
                        TclList.append(interp, list, TclString.newInstance("after#" + id));
                    }
                    interp.resetResult();
                    interp.setResult(list);
                    return(TCL.CompletionCode.RETURN);
                }
                if (argv.Length != 3)
                {
                    throw new TclNumArgsException(interp, 2, argv, "?id?");
                }

                /*
                 * Return command and type of the given after id.
                 */


                info = getAfterEvent(argv[2].ToString());
                if (info == null)
                {
                    throw new TclException(interp, "event \"" + argv[2] + "\" doesn't exist");
                }
                TclObject list2 = TclList.newInstance();
                TclList.append(interp, list2, ((info is TimerInfo) ? ((TimerInfo)info).command : ((IdleInfo)info).command));
                TclList.append(interp, list2, TclString.newInstance((info is TimerInfo) ? "timer" : "idle"));

                interp.resetResult();
                interp.setResult(list2);
                break;
            }
            return(TCL.CompletionCode.RETURN);
        }
Exemple #11
0
 internal TimerInfo(AfterCmd enclosingInstance, Notifier n, int milliseconds)
     : base(n, milliseconds)
 {
     InitBlock(enclosingInstance);
 }
 internal BgError(BgErrorMgr enclosingInstance, Notifier n) : base(n)
 {
     InitBlock(enclosingInstance);
 }