From 5e580e6e2ce70d4c770952fd768c4f8f9dd9a9ed Mon Sep 17 00:00:00 2001
From: faush01 <shaun@bluebit.com.au>
Date: Sat, 14 Mar 2015 13:04:18 +1100
Subject: [PATCH] use the new get machine id code to fix a race condition bug

---
 resources/lib/ClientInformation.py | 47 +++++++++++++++++++++---------
 resources/lib/ConnectionManager.py | 10 +++----
 resources/lib/Lock.py              | 40 +++++++++++++++++++++++++
 3 files changed, 77 insertions(+), 20 deletions(-)
 create mode 100644 resources/lib/Lock.py

diff --git a/resources/lib/ClientInformation.py b/resources/lib/ClientInformation.py
index 915e67e9..c4959c51 100644
--- a/resources/lib/ClientInformation.py
+++ b/resources/lib/ClientInformation.py
@@ -2,7 +2,8 @@ from uuid import uuid4 as uuid4
 import xbmc
 import xbmcaddon
 import xbmcgui
-
+import os
+from Lock import Lock
 
 class ClientInformation():
 
@@ -11,21 +12,39 @@ class ClientInformation():
         WINDOW = xbmcgui.Window( 10000 )
         
         clientId = WINDOW.getProperty("client_id")
-        self.addonSettings = xbmcaddon.Addon(id='plugin.video.mb3sync')
-        if(clientId == None or clientId == ""):
-            xbmc.log("CLIENT_ID - > No Client ID in WINDOW")
-            clientId = self.addonSettings.getSetting('client_id')
+        if(clientId != None and clientId != ""):
+            return clientId
+            
+        # we need to load and or generate a client machine id    
+        __addon__ = xbmcaddon.Addon(id='plugin.video.mb3sync')
+        __addondir__ = xbmc.translatePath( __addon__.getAddonInfo('path'))
+        machine_guid_lock_path = os.path.join(__addondir__, "machine_guid.lock")
+        machine_guid_path = os.path.join(__addondir__, "machine_guid")
+        clientId = ""
         
-            if(clientId == None or clientId == ""):
-                xbmc.log("CLIENT_ID - > No Client ID in SETTINGS")
-                uuid = uuid4()
-                clientId = str("%012X" % uuid)
+        try:
+            lock = Lock(machine_guid_lock_path)
+            locked = lock.acquire()
+            
+            if(locked == True):
+            
+                fd = os.open(machine_guid_path, os.O_CREAT|os.O_RDWR)
+                clientId = os.read(fd, 256)
+                
+                if(len(clientId) == 0):
+                    uuid = uuid4()
+                    clientId = str("%012X" % uuid)
+                    xbmc.log("CLIENT_ID - > Client ID saved to FILE : " + clientId)                    
+                    os.write(fd, clientId)
+                    os.fsync(fd)
+                    
+                os.close(fd)
+                
+                xbmc.log("CLIENT_ID - > Client ID saved to WINDOW : " + clientId)
                 WINDOW.setProperty("client_id", clientId)
-                self.addonSettings.setSetting('client_id', clientId)
-                xbmc.log("CLIENT_ID - > New Client ID : " + clientId)
-            else:
-                WINDOW.setProperty('client_id', clientId)
-                xbmc.log("CLIENT_ID - > Client ID saved to WINDOW from Settings : " + clientId)
+                 
+        finally: 
+            lock.release()
                 
         return clientId
         
diff --git a/resources/lib/ConnectionManager.py b/resources/lib/ConnectionManager.py
index 6a9b5995..bc74f191 100644
--- a/resources/lib/ConnectionManager.py
+++ b/resources/lib/ConnectionManager.py
@@ -102,12 +102,10 @@ class ConnectionManager():
         if(return_value > -1):
             selected_user = userList[return_value]
             self.printDebug("Setting Selected User : " + selected_user)
-            if self.addonSettings.getSetting("port") != server_port:
-                self.addonSettings.setSetting("port", server_port)
-            if self.addonSettings.getSetting("ipaddress") != server_address:        
-                self.addonSettings.setSetting("ipaddress", server_address)        
-            if self.addonSettings.getSetting("username") != selected_user:          
-                self.addonSettings.setSetting("username", selected_user)
+            self.addonSettings.setSetting("port", server_port)
+            self.addonSettings.setSetting("ipaddress", server_address)        
+            self.addonSettings.setSetting("username", selected_user)
+            downloadUtils.authenticate()
                 
     def getServerDetails(self):
 
diff --git a/resources/lib/Lock.py b/resources/lib/Lock.py
new file mode 100644
index 00000000..169f1ab1
--- /dev/null
+++ b/resources/lib/Lock.py
@@ -0,0 +1,40 @@
+import os
+import time
+import errno
+import xbmc
+
+class Lock:
+    
+    def __init__(self, filename):
+        self.filename = filename
+        self.delay = 0.5
+        self.timeout = 10
+        self.is_locked = False
+        self.fd = None
+    
+    def acquire(self):
+        start_time = time.time()
+        while True:
+            try:
+                self.fd = os.open(self.filename, os.O_CREAT|os.O_RDWR|os.O_EXCL)
+                break;
+            except OSError as e:
+                if (time.time() - start_time) >= self.timeout:
+                    xbmc.log("File_Lock_On " + self.filename + " timed out")
+                    return False
+                #xbmc.log("File_Lock_On " + self.filename + " error " + str(e))
+            time.sleep(self.delay)
+        self.is_locked = True
+        xbmc.log("File_Lock_On " + self.filename + " obtained")
+        return True
+        
+    def release(self):
+        if self.is_locked:
+            os.close(self.fd)
+            os.unlink(self.filename)
+            self.is_locked = False
+            xbmc.log("File_Lock_On " + self.filename + " released")
+        
+    def __del__(self):
+        self.release()
+        
\ No newline at end of file