From 1a2a2c6ec9e5dbf0703475ab7c91b06194c23395 Mon Sep 17 00:00:00 2001 From: Tim Kellogg Date: Thu, 22 Aug 2013 07:21:57 -0700 Subject: [PATCH 1/2] Lock was being held for far too long --- MqttLib/Core/QoSManager.cs | 43 ++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/MqttLib/Core/QoSManager.cs b/MqttLib/Core/QoSManager.cs index eaf4821..dc2bb75 100644 --- a/MqttLib/Core/QoSManager.cs +++ b/MqttLib/Core/QoSManager.cs @@ -1,5 +1,7 @@ using System; using System.Collections; +using System.Collections.Generic; +using System.Linq; using System.Text; using System.Threading; using MqttLib.Core.Messages; @@ -158,34 +160,35 @@ public void PublishAccepted(ushort messageID, bool accepted) } } + private List GetResendMessages(DateTime now) + { + lock (_messages) + { + return _messages.Values.Cast() + .Where(x => (now - new DateTime(x.Timestamp)).TotalMilliseconds >= _resendInterval) + .ToList(); // Force enumeration so we can release the lock + } + } + private void MessageDaemon() { // NOTE: This function should be called in it's own thread - while (_running) { + var now = DateTime.Now; // Check if we should re-send some messages - lock (_messages) + foreach (var mess in GetResendMessages(now)) { - DateTime now = DateTime.Now; - - foreach (MqttMessage mess in _messages.Values) + mess.Timestamp = now.Ticks; + mess.Duplicate = true; + try { - TimeSpan ts = now - new DateTime(mess.Timestamp); - if( ts.TotalMilliseconds >= _resendInterval ) - { - mess.Timestamp = now.Ticks; - mess.Duplicate = true; - try - { - Log.Write( LogLevel.DEBUG, "Re-Sending - " + mess.MessageID); - _strManager.SendMessage(mess); - } - catch (Exception e) { - Log.Write(LogLevel.ERROR, e.ToString()); - // If we fail for some reason, we will try again another time automatically - } - } + Log.Write( LogLevel.DEBUG, "Re-Sending - " + mess.MessageID); + _strManager.SendMessage(mess); + } + catch (Exception e) { + Log.Write(LogLevel.ERROR, e.ToString()); + // If we fail for some reason, we will try again another time automatically } } Thread.Sleep(2000); From a2910dfa7a35da2a4a2abc61becc6a11074ac767 Mon Sep 17 00:00:00 2001 From: Tim Kellogg Date: Thu, 22 Aug 2013 07:25:00 -0700 Subject: [PATCH 2/2] OnPublished wasn't being called for QoS 2 --- MqttLib/Mqtt.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MqttLib/Mqtt.cs b/MqttLib/Mqtt.cs index d637f67..c9b97a9 100644 --- a/MqttLib/Mqtt.cs +++ b/MqttLib/Mqtt.cs @@ -99,6 +99,8 @@ void qosManager_MessageReceived(object sender, MqttMessageReceivedEventArgs e) OnPublished(new CompleteArgs(puback.AckID)); break; case MessageType.PUBCOMP: + var puback2 = (MqttPubcompMessage)e.Message; + OnPublished(new CompleteArgs(puback2.AckID)); break; case MessageType.PUBLISH: MqttPublishMessage m = (MqttPublishMessage)e.Message;