// State machine /// <summary> Sets the state and notifies all objects that wait on JmDNS.</summary> internal virtual void AdvanceState() { lock (this) { state = state.Advance(); Monitor.PulseAll(this); } }
public void Run(object state) { DNSOutgoing out_Renamed = null; try { // send probes for JmDNS itself if (Enclosing_Instance.State == taskState) { if (out_Renamed == null) { out_Renamed = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA); } DNSRecord answer = Enclosing_Instance.localHost.DNS4AddressRecord; if (answer != null) { out_Renamed.AddAnswer(answer, 0); } answer = Enclosing_Instance.localHost.DNS6AddressRecord; if (answer != null) { out_Renamed.AddAnswer(answer, 0); } Enclosing_Instance.AdvanceState(); } // send announces for services // Defensively copy the services into a local list, // to prevent race conditions with methods registerService // and unregisterService. IList list; lock (Enclosing_Instance) { list = new ArrayList(Enclosing_Instance.services.Values); } foreach (ServiceInfo info in list) { lock (info) { if (info.State == taskState && info.task == this) { info.AdvanceState(); logger.Debug("run() JmDNS announcing " + info.QualifiedName + " state " + info.State); if (out_Renamed == null) { out_Renamed = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA); } out_Renamed.AddAnswer(new Pointer(info.type, DNSConstants.TYPE_PTR, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, info.QualifiedName), 0); out_Renamed.AddAnswer(new Service(info.QualifiedName, DNSConstants.TYPE_SRV, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, info.priority, info.weight, info.port, Enclosing_Instance.localHost.Name), 0); out_Renamed.AddAnswer(new Text(info.QualifiedName, DNSConstants.TYPE_TXT, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, info.text), 0); } } } if (out_Renamed != null) { logger.Debug("run() JmDNS announcing #" + taskState); Enclosing_Instance.Send(out_Renamed); } else { // If we have nothing to send, another timer taskState ahead // of us has done the job for us. We can cancel. cancel(); } } catch (Exception e) { logger.Warn("run() exception ", e); Enclosing_Instance.Recover(); } taskState = taskState.Advance(); if (!taskState.Announcing) { cancel(); new Renewer(enclosingInstance).start(); } }