void ProcOptx(String s, OutPort opt) { int i = opt.setDimension; String t = s; if (!s.EndsWith("*")) { i = 0; } else { t = s.Substring(0, s.Length - 1); if (i == 0) { FlowError.Complain(_name + "." + s + ": Asterisk specified on output port name, but setDimension was not specified"); } } if (i == 0) { ProcOpty(t, opt); } else { for (int j = 0; j < i; j++) { ProcOpty(t + j, opt); } } }
internal void CheckOwner(Packet p) { if (this != p._owner) { FlowError.Complain("Packet not owned by current Component"); } }
internal void Decrement(int freq) { _dur -= freq; // reduce by frequency, in msecs if (_dur < 0) { FlowError.Complain("Component " + _comp.Name + " timed out"); } }
/// <summary>Stores the Component class object with its Network name in the Hashtable called /// 'components' /// </summary> protected internal Component Component(string name, System.Type type) { if (_components.ContainsKey(name)) { FlowError.Complain("Attempt to redefine Component " + name); } Component c = null; //UPGRADE_NOTE: Exception 'java.lang.InstantiationException' was converted to ' ' which has different behavior. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1100"' Type foundType = null; Assembly engine = System.Reflection.Assembly.GetCallingAssembly(); foundType = FindType(engine, type); if (foundType == null) { // Search for all DLLs in the folder foreach (string strFile in Directory.GetFiles(_strPath, "*.dll")) { // Open the class library. engine = Assembly.LoadFrom(strFile); foundType = FindType(engine, type); if (foundType != null) { break; } } } if (foundType == null) { FlowError.Complain("Component not found: " + type.FullName); } try { //ConstructorInfo cnst = foundType.GetConstructor(Type.EmptyTypes); //c = (Component)(cnst.Invoke(null)); c = NewComponent(foundType, name, this); } catch (System.UnauthorizedAccessException e) { FlowError.Complain("Illegal access to Component " + type.FullName); return(null); // unreachable } catch (System.Exception e) { FlowError.Complain(e.ToString()); return(null); // unreachable } c.Type = foundType; c.Name = name; //c._network = this; //c._mother = this; _components.Add(name, c); c._network = this; return(c); }
/// <summary>method to register a port name /// </summary> public Port Port(string name) { if (!name.Equals("*") && !name.Equals("*SUBEND") && -1 != name.IndexOf('*')) { FlowError.Complain("Stray * in port name " + name); } Port p = new Port(name, -1); //p.displayName = String.Format("{0}", name); return(p); }
/// <summary>method to register a port (with index) /// </summary> protected internal Port Port(string name, int index) { if (!name.Equals("*") && -1 != name.IndexOf('*')) { FlowError.Complain("Stray * in port name " + name); } Port p = new Port(name, index); //p.displayName = String.Format("{0}[{1}]", name, index); return(p); }
/// <summary>Returns a Component class object, given the Component name in the Network /// </summary> protected internal Component Component(string name) { if (!_components.ContainsKey(name)) { FlowError.Complain("Reference to unknown Component " + name); } Component c = (Component)(_components[name]); c.Name = name; return(c); }
//---// // splits a string into component part and port part string[] CPSplit(string s) { int i = s.IndexOf("."); if (i < 0) { FlowError.Complain("Invalid receiver string: " + s); } string[] p = { s.Substring(0, i), s.Substring(i + 1) }; return(p); }
protected internal IInputPort[] OpenInputArray(string name, int arraySize) { if (name.StartsWith("*")) { FlowError.Complain("Attempt to open * port: " + this + "." + name); } if (!_inputPorts.ContainsKey(name)) { FlowError.Complain("Port not defined as input array in metadata: " + this._name + "." + name); } var o = _inputPorts[name]; if (!(o is ConnArray)) { FlowError.Complain("Port not defined as input array in metadata: " + this._name + "." + name); } var ca = o as ConnArray; if (!(ca._fixedSize ^ arraySize == 0)) { FlowError.Complain("Array port fixedSize option in metadata doesn't match specified size: " + this._name + "." + name); } IInputPort[] array = GetPortArray(_inputPorts, name); if (arraySize > 0 && array.Length > arraySize) { FlowError.Complain("Number of elements specified for array port less than actual number used: " + this._name + "." + name); } if (arraySize > 0 && array.Length < arraySize) { Array.Resize(ref array, arraySize); } for (int i = 0; i < array.Length; i++) { if (array[i] == null) { array[i] = new NullConnection { Name = Name + "." + name + "[" + i + "]" } } ; } _inputPorts.Remove(name); return(array); }
protected internal void Initialize(object param, string receiver) { string r1, r2; int i; if ((i = receiver.IndexOf('.')) == -1) { FlowError.Complain("invalid receiver name" + receiver); } r1 = receiver.Substring(0, i); // start, length r2 = receiver.Substring(i + 1); // start Initialize(param, Component(r1), Port(r2)); }
protected internal void ProcIpt(InPort ipt) { if (!(ipt.value.Equals("") ^ ipt.valueList == null)) { FlowError.Complain(_name + ": @InPort must have value or valueList, but not both"); } String s; if (!ipt.value.Equals("")) { s = ipt.value; } else { s = ipt.valueList[0]; } if (ipt.fixedSize && !ipt.arrayPort) { FlowError.Complain(_name + "." + s + ": @InPort specified fixedSize but not arrayPort"); } if (!ipt.value.Equals("")) { if (ipt.setDimension > 0 && !ipt.value.EndsWith("*")) { FlowError.Complain(_name + "." + s + ": @InPort specified setDimension but value string did not end with asterisk"); } ProcIptx(ipt.value, ipt); } else { bool asterisk_found = false; foreach (String t in ipt.valueList) { if (t.EndsWith("*")) { asterisk_found = true; } ProcIptx(t, ipt); } if (!asterisk_found && ipt.setDimension > 0) { FlowError.Complain(_name + "." + s + ": @InPort specified setDimension but valueList did not contain any strings ending with asterisks"); } } }
// Get array of ports in the form name[] T[] GetPortArray <T>(Dictionary <string, T> ports, string name) { T[] ret = null; Regex re = new Regex(@"^(\w+)(\[(\d+)\])?$"); foreach (KeyValuePair <string, T> kvp in ports) { Match m = re.Match(kvp.Key); if (!m.Success) { FlowError.Complain("Invalid port name :" + kvp.Key); } if (!(kvp.Value is T)) // ignore other types than IInputPort or OutputPort (depending on T) { continue; } string s = m.Groups[1].Value; if (!s.Equals(name)) { continue; } int subs = 0; if (m.Groups[2].Value.Equals("")) { continue; } subs = Convert.ToInt32(m.Groups[3].Value); if (subs < 0 || subs >= 1000) { FlowError.Complain("bad subscript " + name); } if (ret == null) { ret = new T[0]; } if (subs >= ret.Length) { Array.Resize(ref ret, subs + 1); } ret[subs] = kvp.Value; } return(ret); }
/// <summary> Verbs call this method from their <code>openPorts</code> method /// to open an output port. /// </summary> /// <param name="name">the name of the OutputPort /// </param> /// <returns>the OutputPort, which should be assigned to an instance variable /// * /// </returns> protected internal OutputPort OpenOutput(string name) { if (name.StartsWith("*")) { FlowError.Complain("Attempt to open * port: " + this + "." + name); } if (!_outputPorts.ContainsKey(name)) { FlowError.Complain("Port not specified in metadata: " + this + "." + name); } var o = _outputPorts[name]; if (o is OutArray) { FlowError.Complain("Port is defined as output array in metadata: " + this._name + "." + name); } return(o); }
/// <summary>Maintains a Chain of Packets attached to this Packet. /// A Packet may have multiple named Chains attached to it, accessed via a Hashtable. /// Since Packets are attached to Chains, as well as Chains to Packets, /// this results in an alternation of Packets and Chains, creating a tree structure. /// </summary> internal virtual void Attach(string name, Packet subordinate) { if (subordinate == null) { FlowError.Complain("Null packet reference in 'Attach' method call"); } Packet p = this; while (p._owner is Packet) { if (p == subordinate) { FlowError.Complain("Loop in tree structure"); } p = (Packet)p._owner; } if (p == subordinate) { FlowError.Complain("Loop in tree structure"); } if (p._owner != Thread.CurrentThread) { FlowError.Complain("Packet not owned (directly or indirectly) by current component"); } if (subordinate._owner != Thread.CurrentThread) { FlowError.Complain("Subordinate packet not owned by current component"); } if (_chains == null) { _chains = new Dictionary <string, Chain>(); } Chain chain = (Chain)(_chains[name]); if (chain == null) { chain = new Chain(name); _chains.Add(name, chain); } subordinate.Owner = this; chain.Members.Add(subordinate); }
/// <summary> Verbs call this method from their <code>openPorts</code> method to /// open an IInputPort, either a regular port or a parameter port. /// </summary> /// <param name="name">the name of the IInputPort /// </param> /// <returns>the IInputPort, which should be assigned to an /// instance variable of the verb /// * /// </returns> protected internal IInputPort OpenInput(string name) { if (name.StartsWith("*")) { FlowError.Complain("Attempt to open * port: " + this + "." + name); } if (!_inputPorts.ContainsKey(name)) { FlowError.Complain("Port not specifed in metadata: " + this + "." + name); } Object o = _inputPorts[name]; if (o is ConnArray) { FlowError.Complain("Port is defined as input array in metadata: " + this._name + "." + name); } return((IInputPort)o); }
internal static Component NewComponent(Type type, string name, Network network) { ConstructorInfo ci = type.GetConstructor(Type.EmptyTypes); Component cp = null; try { cp = (Component)ci.Invoke(null); } catch (TargetInvocationException e) { FlowError.Complain("Target Invocation Exception to " + type.FullName); return(null); // unreachable } //cp._type = type; //cp._name = name; cp._mother = network; cp._type = type; cp._name = name; cp._network = network; return(cp); }
/// <summary> Send a packet to this Port. /// The thread is suspended if no capacity is currently available. /// If the port or connection has been closed, <code>false</code> is /// returned; otherwise, <code>true</code> is returned. /// <p> Do not reference the packet after sending - someone else may be /// modifying it! /// </summary> /// <param name="packet">packet to send /// </param> /// <returns>true if successful /// * /// </returns> // The send function. public virtual void Send(Packet packet) { bool res = true; Trace("Sending: " + packet.ToString()); _sender.CheckOwner(packet); if (isClosed) { Trace("Sending - port closed"); res = false; } res &= _cnxt.Send(packet, this); // fire up send method on connection if (!res) { FlowError.Complain("Could not deliver packet to " + Name); } Trace("Sent OK"); return; }
/// <summary>Build InitializationConnection object /// </summary> /// <summary>Build InitializationConnection object /// </summary> protected internal void Initialize(System.Object content, Component receiver, Port inP) { IInputPort ip = receiver._inputPorts[inP._displayName]; if (ip == null) { FlowError.Complain("Input port not defined in metadata: " + receiver._name + "." + inP._displayName); } if (ip is Connection || ip is ConnArray) { FlowError.Complain("IIP port cannot be shared: " + receiver._name + "." + inP._displayName); } if (ip is InitializationConnection) { FlowError.Complain("IIP port already used: " + receiver._name + "." + inP._displayName); } if (ip is ConnArray && inP._index == -1) { inP._index = 0; inP._displayName = inP._name + "[" + inP._index + "]"; } if (inP._index > -1 && !(ip is ConnArray)) { FlowError.Complain("Input port not defined as array in metadata: " + receiver._name + "." + inP._displayName); } InitializationConnection ic = new InitializationConnection(content, receiver); ic._name = receiver._name + "." + inP._displayName; //ic.network = this; receiver._inputPorts.Remove(inP._displayName); receiver._inputPorts.Add(inP._displayName, ic); }
/* Connects */ /// <summary>Connect an output port of one Component to an input port /// of another /// </summary> protected internal Connection Connect(Component sender, Port outP, Component receiver, Port inP, int size, bool IPCount) { int cap = size; if (size == 0) { cap = _defaultCapacity; } //string outName = outPort.displayName; //string inName = inPort.displayName; if (outP._displayName.Equals("*")) { outP._name = "*OUT"; outP._displayName = "*OUT"; } if (inP._displayName.Equals("*")) { inP._name = "*IN"; inP._displayName = "*IN"; } OutputPort op = null; if (!outP._displayName.Substring(0, 1).Equals("*")) { op = sender._outputPorts[outP._name]; // try to find output port with port name - no index if (op == null) { FlowError.Complain("Output port not defined in metadata: " + sender._name + "." + outP._displayName); } if (op is OutArray && outP._index == -1) { outP._index = 0; outP._displayName = outP._name + "[" + outP._index + "]"; } if (outP._index > -1 && !(op is OutArray)) { FlowError.Complain("Output port not defined as array in metadata: " + sender._name + "." + outP._displayName); } if (!(op is NullOutputPort) && !(op is OutArray) && op._cnxt != null) { FlowError.Complain("Multiple connections to output port:" + sender._name + ' ' + outP._displayName); } } op = new OutputPort(); op.SetSender(sender); op._name = outP._displayName; op._connected = true; op._fullName = sender._name + "." + outP._displayName; op._traceNetwork = sender._mother; sender._outputPorts.Remove(op._name); sender._outputPorts.Add(op._name, op); /* start processing input port */ IInputPort ip = null; if (!inP._displayName.Substring(0, 1).Equals("*")) { ip = receiver._inputPorts[inP._name]; if (ip == null) { FlowError.Complain("Input port not defined in metadata: " + receiver._name + "." + inP._displayName); } if (ip is ConnArray && inP._index == -1) { inP._index = 0; inP._displayName = inP._name + "[" + inP._index + "]"; } if (inP._index > -1 && !(ip is ConnArray)) { FlowError.Complain("Input port not defined as array in metadata: " + receiver._name + "." + inP._displayName); } } Connection c; if (ip is Connection) { if (size != 0 && size != cap) { FlowError.Complain("Connection capacity does not agree with previous specification\n " + receiver._name + "." + inP._displayName); } c = (Connection)ip; } else { if (ip is InitializationConnection) { FlowError.Complain("Mixed connection to input port: " + receiver._name + "." + inP._displayName); } c = new Connection(cap); c.SetReceiver(receiver); c._name = inP._displayName; c._IPCount = IPCount; c._fullName = receiver._name + "." + c._name; receiver._inputPorts.Remove(c._name); receiver._inputPorts.Add(c._name, c); } c.BumpSenderCount(); op._cnxt = c; c._receiver = receiver; c._fullName = receiver.Name + "." + inP._displayName; return(c); }
/// <summary>Test if Network as a whole has terminated /// </summary> internal virtual void WaitForAll() { bool possibleDeadlock = false; //bool deadlock = false; int freq = 500; // check every .5 second //Settings s = Settings.Default; while (true) { if (_cdl.Await(new TimeSpan(0, 0, 0, 0, freq))) // 500 msecs { break; // if CountDownLatch finished, exit } // if an error occurred, skip deadlock testing if (_error != null) { break; } // if the network was aborted, skip deadlock testing if (_abort) { break; } if (!_deadlockTest) { continue; } bool deadlockTestEnabled; System.AppContext.TryGetSwitch("DeadlockTestEnabled", out deadlockTestEnabled); if (deadlockTestEnabled) { TestTimeouts(freq); if (!_active) // else interval elapsed { if (!possibleDeadlock) { possibleDeadlock = true; } else { _deadlock = true; // well, maybe // so test state of components _msgs = new List <String>(); _msgs.Add("Network has deadlocked"); if (ListCompStatus(_msgs)) { // interruptAll(); foreach (string m in _msgs) { Console.Out.WriteLine(m); } Console.Out.WriteLine("*** Deadlock detected in Network "); Console.Out.Flush(); // terminate the net instead of crashing the application Terminate(); // tell the caller a deadlock occurred FlowError.Complain("Deadlock detected in Network"); break; } // one or more components haven't started or // are in a long wait _deadlock = false; possibleDeadlock = false; } } _active = false; } } if (_deadlock) { InterruptAll(); } else { foreach (Component c in _components.Values) { if (c._thread != null) { c._thread.Join(); } } //if (outputCopier != null) // outputCopier.Join(); } }
public override void Execute() { OutputPort subEndPort = null; if (_status != States.Error) { //_network.Trace(this.Name + ": started"); _components.Clear(); //_tracing = _mother._tracing; //_traceFileList = _mother._traceFileList; subEndPort = _outputPorts["*SUBEND"]; try { CallDefine(); bool res = true; foreach (Component comp in _components.Values) { res &= comp.CheckPorts(); } if (!res) { FlowError.Complain("One or more mandatory connections have been left unconnected: " + Name); } _cdl = new CountDownLatch(_components.Count); Initiate(); // activateAll(); // don't do deadlock testing in subnets - you need to consider the whole net! _deadlockTest = false; WaitForAll(); foreach (IInputPort ip in _inputPorts.Values) { if (ip is InitializationConnection) { InitializationConnection ic = (InitializationConnection)ip; ic.Close(); } } /* * Iterator allout = (outputPorts.values()).iterator(); * * while (allout.hasNext()) { * * * OutputPort op = (OutputPort) allout.next(); op.close(); * * } */ // status = Component.StatusValues.TERMINATED; //will not be set if // never activated // mother.indicateTerminated(this); _network.Trace(this.Name + ": closed down"); if (subEndPort != null) { subEndPort.Send(Create(null)); } } catch (FlowError e) { string s = "Flow Error :" + e; Console.Out.WriteLine("Network: " + s); throw e; } } }
/// <summary>The send function. See OutputPort.send. /// </summary> //UPGRADE_NOTE: Synchronized keyword was removed from method 'send'. Lock expression was added. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1027"' internal bool Send(Packet packet, OutputPort op) { lock (this) { if (packet == null) { throw new System.ArgumentException(); } _sender = op._sender; if (IsClosed()) { return(false); } //_sender._mother.Trace(Name + ": Sending: " + packet); if (IsEmpty()) { System.Threading.Monitor.PulseAll(this); } while (IsFull()) { if (_dropOldest) { Packet p = _buffer.Take(); Interlocked.Increment(ref Network.dropOlds); _sender._mother.Trace("{0}: DropOldest", _sender.Name); } else { _sender.Status = Component.States.SuspSend; _sender._mother.Trace("{0}: Send/susp", _sender.Name); try { System.Threading.Monitor.Wait(this); } catch (System.Threading.ThreadInterruptedException e) { //UPGRADE_NOTE: Exception 'java.lang.ThreadDeath' was converted to ' ' which has different behavior. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1100"' // throw new System.ApplicationException(); IndicateOneSenderClosed(); FlowError.Complain(_sender._name + ": interrupted"); // unreachable code return(false); } // if (Component._network._deadlock) //{ // _sender._thread.Interrupt(); // _sender._mother.Trace(_sender._name + ": Send interrupted because of deadlock"); // // unreachable code // return false; // } _sender = op._sender; _sender.Status = Component.States.Active; _sender._mother.Trace("{0}: Send/resume", _sender.Name); } } if (IsClosed()) { _sender._mother.Trace("{0}: Send/close", _sender.Name); //Interlocked.Increment(ref Network.sends); return(false); } //lock ((_receiver._inputPorts as ICollection).SyncRoot) try { Monitor.Enter(_receiver._lockObject); packet.ClearOwner(); _buffer.Put(packet); if (_receiver.Status == Component.States.Dormant || _receiver.Status == Component.States.NotStarted) { _receiver.Activate(); } else { System.Threading.Monitor.PulseAll(this); } _sender._network._active = true; _sender = null; } catch (ThreadInterruptedException e) { return(false); } finally { Monitor.Exit(_receiver._lockObject); } Interlocked.Increment(ref Network.sends); return(true); } }
public override void Execute() { Packet np = _nameport.Receive(); if (np == null) { return; } _nameport.Close(); string pname = np.Content as string; Drop(np); _inport = (_mother._inputPorts)[pname] as IInputPort; _mother.Trace(Name + ": Accessing input port: " + _inport.Name); Packet p; int level = 0; // I think this works! Component oldReceiver = _inport.Receiver; if (_inport is InitializationConnection) { FlowError.Complain("SubinSS cannot support IIP - use Subin"); } Connection cnxt = _inport as Connection; cnxt.SetReceiver(this); while ((p = cnxt.Receive()) != null) { p.Owner = this; if (p.Type == Packet.Types.Open) { if (level == 0) { Drop(p); _network.Trace("{0}: Open bracket detected", Name); } else { _outport.Send(p); } level++; } else if (p.Type == Packet.Types.Close) { level--; if (level == 0) { Drop(p); _network.Trace("{0}: Close bracket detected", Name); } else { _outport.Send(p); } break; } else { _outport.Send(p); } } // inport.close(); _mother.Trace(Name + ": Releasing input port: " + _inport.Name); cnxt.SetReceiver(oldReceiver); // inport = null; }
protected internal OutputPort[] OpenOutputArray(string name, int arraySize) { if (name.StartsWith("*")) { FlowError.Complain("Attempt to open * port: " + this + "." + name); } if (!_outputPorts.ContainsKey(name)) { FlowError.Complain("Port not defined as output array in metadata: " + this._name + "." + name); } var o = _outputPorts[name]; if (!(o is OutArray)) { FlowError.Complain("Port not defined as output array in metadata: " + this._name + "." + name); } var oa = o as OutArray; if (!(oa._fixedSize ^ arraySize == 0)) { FlowError.Complain("Array port fixedSize option in metadata doesn't match specified size: " + this._name + "." + name); } OutputPort[] array = GetPortArray(_outputPorts, name); if (array == null && !oa._optional) { FlowError.Complain("No elements defined in mandatory output array port: " + this._name + "." + name); } if (array != null) { if (arraySize > 0 && array.Length > arraySize) { FlowError.Complain("Number of elements specified for array port less than actual number used: " + this._name + "." + name); } if (arraySize > 0 && array.Length < arraySize) { Array.Resize(ref array, arraySize); } for (int i = 0; i < array.Length; i++) { if (array[i] == null) { if (!oa._optional && arraySize > 0) { FlowError.Complain("Mandatory output array port has missing elements: " + this._name + "." + name); } array[i] = new NullOutputPort { _sender = this, Name = Name + "." + name + "[" + i + "]" }; } } } _outputPorts.Remove(name); return(array); }
public Task GoAsync() { Type t = this.GetType(); Name = t.FullName; _network = this; DateTime now = DateTime.Now; InitBlock(); var task = Task.Run(() => { try { CallDefine(); bool res = true; foreach (Component comp in _components.Values) { res &= comp.CheckPorts(); } if (!res) { FlowError.Complain("One or more mandatory connections have been left unconnected: " + Name); } _cdl = new CountDownLatch(_components.Count); Trace(Name + ": run started"); _active = true; Initiate(); WaitForAll(); } catch (FlowError e) { string s = "Flow Error :" + e; Console.Out.WriteLine("Network: " + s); Console.Out.Flush(); // rethrow the exception for external error handling // in case of a deadlock: deadlock is the cause throw e; } if (_error != null) { // throw the exception which caused the network to stop throw _error; } TimeSpan duration = DateTime.Now - now; Console.Out.WriteLine("{0} - run time: {1}", Name, duration); Console.Out.WriteLine("Counts: C: {0}, D: {1}, S: {2}, R (non-null): {3}, DO: {4}", creates, drops, sends, receives, dropOlds); CloseTraceFiles(); }); return(task); }
//UPGRADE_TODO: The equivalent of method java.lang.Runnable.run is not an override method. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca5065"' // internal void Run() // implement mainline for thread // runs and keeps running as long as there are input ports to read void ThreadMain() { try { if (IsTerminated() || HasError()) { try { Monitor.Exit(_lockObject); } catch (SynchronizationLockException e) { // do nothing - this is OK! } return; } bool componentExecutedAtLeastOnce = false; _status = States.Active; _mother.Trace("{0}: Started", Name); _ = _inputPorts.TryGetValue("*IN", out _autoInput); _ = _outputPorts.TryGetValue("*OUT", out _autoOutput); if (_autoInput != null) { Packet p = _autoInput.Receive(); if (p != null) { Drop(p); } _autoInput.Close(); } InputStates ist = null; //if (SelfStarting) // _autoStarting = true; //else //if componentent has connected non IIP inputports, but is not selfstarting if (!SelfStarting) { try { ist = new InputStates(_inputPorts, this); } catch (ThreadInterruptedException ex) { if (IsTerminated() || HasError()) { // if we are in the TERMINATED or ERROR state we terminated intentionally return; } // otherwise there was an error throw ex; } } while (SelfStarting || _autoStarting || !ist.allDrained || _autoInput != null || ist.allDrained && MustRun || StackSize() > 0) { _autoInput = null; if (_network._deadlock || IsTerminated()) { break; } _packetCount = 0; foreach (IInputPort port in _inputPorts.Values) { if (port is InitializationConnection icx) { icx.Reopen(); } } _mother.Trace("{0}: Activated", Name); try { componentExecutedAtLeastOnce = true; Execute(); // do one activation! } catch (ComponentException e) { _mother.Trace("Component Exception: " + Name + " - " + e.Message); if (e.Message.StartsWith("*")) { string s = e.Message.Substring(1); FlowError.Complain("Component Exception: " + Name + " - " + s); } else { Console.Out.WriteLine("! Component Exception: " + Name + " - " + e.Message); } } _mother.Trace("{0}: Deactivated", Name); if (_packetCount != 0) { _mother.Trace(Name + " deactivated holding " + _packetCount + " packets"); FlowError.Complain(_packetCount + " packets not disposed of during Component activation of " + Name); } foreach (IInputPort port in _inputPorts.Values) { if (port is InitializationConnection icx) { if (!icx.IsClosed()) { FlowError.Complain("Component deactivated with IIP port not closed: " + icx.Name); } } } MustRun = false; SelfStarting = false; if (_autoStarting) { break; } // lock ((_inputPorts as ICollection).SyncRoot) //{ try { ist = new InputStates(_inputPorts, this); } catch (ThreadInterruptedException ex) { if (IsTerminated() || HasError()) { // if we are in the TERMINATED or ERROR state we terminated intentionally return; } // otherwise there was an error throw ex; } if (ist.allDrained) { break; } //if (_network._deadlock) //{ // break; // } } // while (!ist.allDrained); //_compLog.Trace("{0}: Terminating", Name); //} // catch (System.Exception t) // { //Console.Out.WriteLine("*** Exception detected in " + Name); // System.Diagnostics.Trace.Fail("*** Exception detected in " + Name + ": " + t.Message); // } //_compLog.Trace("{0}: Terminated", Name); if (_autoOutput != null) { //Packet p = Create(""); //_autoOutput.Send(p); _autoOutput.Close(); } _status = States.Terminated; if (_stack.Count > 0) { FlowError.Complain("Stack not empty at component termination: " + Name); } foreach (IInputPort port in _inputPorts.Values) { if (port is Connection cx) { if (cx.Count() > 0) { Console.Out.WriteLine("{0}: Component terminated with {1} packets in input connection", cx.Name, cx.Count()); } while (cx.Count() > 0) { Packet p = cx._buffer.Take(); Console.Out.WriteLine(p); } } else if (port is InitializationConnection iip) { if (componentExecutedAtLeastOnce && !iip.IsClosed()) { FlowError.Complain("Component terminated with input port not closed: " + iip.Name); } } } foreach (OutputPort port in _outputPorts.Values) { port.Close(); } //_status = States.Terminated; //will not be set if never activated //_network.NotifyTerminated(); _mother.NotifyTerminated(this); } catch (Exception e) { // don't tell the mother if we are already in the ERROR or TERMINATE state // because then the mother told us to terminate if (!HasError() && !IsTerminated()) { // an error occurred in this component _status = States.Error; // tell the mother _mother.SignalError(e); } } }
/// <summary>The receive function. /// See IInputPort.receive. /// </summary> //UPGRADE_NOTE: Synchronized keyword was removed from method 'receive'. Lock expression was added. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1027"' public Packet Receive() { lock (this) { Trace("Receiving"); if (IsDrained()) { Trace("Recv/close"); return(null); } Interlocked.Increment(ref Network.receives); while (IsEmpty()) { _receiver.Status = Component.States.SuspRecv; Trace("Recv/susp"); try { System.Threading.Monitor.Wait(this); } catch (System.Threading.ThreadInterruptedException e) { //UPGRADE_NOTE: Exception 'java.lang.ThreadDeath' was converted to ' ' which has different behavior. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1100"' // throw new System.ApplicationException(); Close(); FlowError.Complain(_receiver._name + ": Interrupted"); // unreachable return(null); } //if (Component._network._deadlock) // { // _receiver._thread.Interrupt(); // Trace("Receive interrupted because of deadlock"); // return null; // } _receiver.Status = Component.States.Active; Trace("Recv/resume"); if (IsDrained()) { Trace("Receive drained"); return(null); } } if (IsDrained()) { Trace("Receive drained"); return(null); } if (IsFull()) { System.Threading.Monitor.PulseAll(this); } // if was full, notify any Components waiting to send Packet packet = _buffer.Take(); packet.Owner = _receiver; if (null == packet.Content) { Trace("Receive OK"); } else { Trace("Receive OK: " + packet); } _receiver._network._active = true; return(packet); } }