Fixing static lock messup with Ns3 DCE Manager
authorAlina Quereilhac <alina.quereilhac@inria.fr>
Sat, 7 Feb 2015 16:58:32 +0000 (17:58 +0100)
committerAlina Quereilhac <alina.quereilhac@inria.fr>
Sat, 7 Feb 2015 16:58:32 +0000 (17:58 +0100)
src/nepi/resources/linux/ns3/ns3simulation.py
src/nepi/resources/ns3/ns3dceapplication.py
src/nepi/resources/ns3/ns3dcehelper.py [new file with mode: 0644]
src/nepi/resources/ns3/ns3node.py

index 51da3a2..2abdb6f 100644 (file)
@@ -32,9 +32,6 @@ import os
 import time
 import threading
 
-## TODO: Clean up DCE part. All that is DCE specific should go
-##       in the linux ns3dceapplication.py
-
 @clsinit_copy
 class LinuxNS3Simulation(LinuxApplication, NS3Simulation):
     _rtype = "linux::ns3::Simulation"
@@ -139,6 +136,7 @@ class LinuxNS3Simulation(LinuxApplication, NS3Simulation):
         self._home = "ns3-simu-%s" % self.guid
         self._socket_name = "ns3-%s.sock" % os.urandom(4).encode('hex')
         self._enable_dce = None
+        self._dce_helper = None
 
     @property
     def socket_name(self):
@@ -350,10 +348,17 @@ class LinuxNS3Simulation(LinuxApplication, NS3Simulation):
                 rm = self.ec.get_resource(guid)
                 if isinstance(rm, rclass):
                     self._enable_dce = True
+
+                    from nepi.resources.ns3.ns3dcehelper import NS3DceHelper
+                    self._dce_helper = NS3DceHelper(self)
                     break
 
         return self._enable_dce
 
+    @property
+    def dce_helper(self):
+        return self._dce_helper
+        
     @property
     def _start_command(self):
         command = [] 
index fd1c513..0b3d302 100644 (file)
@@ -32,14 +32,6 @@ import threading
 class NS3BaseDceApplication(NS3BaseApplication):
     _rtype = "abstract::ns3::DceApplication"
 
-    # Lock used to synchronize usage of DceManagerHelper 
-    _dce_manager_lock = threading.Lock()
-    # Lock used to synchronize usage of DceApplicationHelper
-    _dce_application_lock = threading.Lock()
-   
-    _dce_manager_helper_uuid = None
-    _dce_application_helper_uuid = None
-
     @classmethod
     def _register_attributes(cls):
         binary = Attribute("binary", 
@@ -92,36 +84,6 @@ class NS3BaseDceApplication(NS3BaseApplication):
     def pid(self):
         return self._pid
 
-    @property
-    def dce_manager_helper_uuid(self):
-        if not NS3BaseDceApplication._dce_manager_helper_uuid:
-                NS3BaseDceApplication._dce_manager_helper_uuid = \
-                        self.simulation.create("DceManagerHelper")
-
-        if self.get("useDlmLoader"):
-            self.simulation.invoke(
-                NS3BaseDceApplication._dce_manager_helper_uuid, 
-                "SetLoader", 
-                "ns3::DlmLoaderFactory")
-
-        return NS3BaseDceApplication._dce_manager_helper_uuid
-
-    @property
-    def dce_application_helper_uuid(self):
-        if not NS3BaseDceApplication._dce_application_helper_uuid:
-                NS3BaseDceApplication._dce_application_helper_uuid = \
-                        self.simulation.create("DceApplicationHelper")
-                        
-        return NS3BaseDceApplication._dce_application_helper_uuid
-
-    @property
-    def dce_manager_lock(self):
-        return NS3BaseDceApplication._dce_manager_lock
-
-    @property
-    def dce_application_lock(self):
-        return NS3BaseDceApplication._dce_application_lock
-
     def _instantiate_object(self):
         pass
 
@@ -132,51 +94,37 @@ class NS3BaseDceApplication(NS3BaseApplication):
 
             # Preventing concurrent access to the DceApplicationHelper
             # from different DceApplication RMs
-            with self.dce_application_lock:
-                self.simulation.invoke(
-                        self.dce_application_helper_uuid, 
-                        "ResetArguments") 
+            dce_helper = self.simulation.dce_helper
+
+            with dce_helper.dce_application_lock:
+                dce_app_uuid = dce_helper.dce_application_uuid
+
+                self.simulation.invoke(dce_app_uuid, "ResetArguments") 
 
-                self.simulation.invoke(
-                        self.dce_application_helper_uuid, 
-                        "ResetEnvironment") 
+                self.simulation.invoke(dce_app_uuid, "ResetEnvironment") 
 
-                self.simulation.invoke(
-                        self.dce_application_helper_uuid, 
+                self.simulation.invoke(dce_app_uuid, 
                         "SetBinary", self.get("binary")) 
 
-                self.simulation.invoke(
-                        self.dce_application_helper_uuid, 
+                self.simulation.invoke(dce_app_uuid, 
                         "SetStackSize", self.get("stackSize")) 
 
                 arguments = self.get("arguments")
                 if arguments:
                     for arg in map(str.strip, arguments.split(";")):
-                        self.simulation.invoke(
-                                self.dce_application_helper_uuid, 
+                        self.simulation.invoke(dce_app_uuid, 
                             "AddArgument", arg)
 
                 environment = self.get("environment")
                 if environment:
                     for env in map(str.strip, environment.split(";")):
                         key, val = env.split("=")
-                        self.simulation.invoke(
-                                self.dce_application_helper_uuid, 
+                        self.simulation.invoke(dce_app_uuid, 
                             "AddEnvironment", key, val)
 
-                apps_uuid = self.simulation.invoke(
-                        self.dce_application_helper_uuid, 
+                apps_uuid = self.simulation.invoke(dce_app_uuid, 
                         "InstallInNode", self.node.uuid)
 
-
-                """
-                container_uuid = self.simulation.create("NodeContainer")
-                self.simulation.invoke(container_uuid, "Add", self.node.uuid)
-                apps_uuid = self.simulation.invoke(
-                        self.dce_application_helper_uuid, 
-                        "Install", container_uuid)
-                """
-
             self._uuid = self.simulation.invoke(apps_uuid, "Get", 0)
 
             if self.has_changed("StartTime"):
@@ -218,8 +166,12 @@ class NS3BaseDceApplication(NS3BaseApplication):
 
         # Using lock to prevent concurrent access to the DceApplicationHelper
         # from different DceApplication RMs
-        with self.dce_application_lock:
-            self._pid = self.simulation.invoke(self.dce_application_helper_uuid, 
+        dce_helper = self.simulation.dce_helper
+
+        with dce_helper.dce_application_lock:
+            dce_app_uuid = dce_helper.dce_application_uuid
+
+            self._pid = self.simulation.invoke(dce_app_uuid, 
                     "GetPid", self.uuid)
 
         node_id = self.node.node_id 
diff --git a/src/nepi/resources/ns3/ns3dcehelper.py b/src/nepi/resources/ns3/ns3dcehelper.py
new file mode 100644 (file)
index 0000000..d0c86c6
--- /dev/null
@@ -0,0 +1,59 @@
+#
+#    NEPI, a framework to manage network experiments
+#    Copyright (C) 2014 INRIA
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: Alina Quereilhac <alina.quereilhac@inria.fr>
+
+import os
+import time
+import threading
+        
+class NS3DceHelper(object):
+    def __init__(self, simulation):
+        self.simulation = simulation
+
+        # Lock used to synchronize usage of DceManagerHelper 
+        self._dce_manager_lock = threading.Lock()
+        # Lock used to synchronize usage of DceApplicationHelper
+        self._dce_application_lock = threading.Lock()
+   
+        self._dce_manager_uuid = None
+        self._dce_application_uuid = None
+
+    @property
+    def dce_manager_uuid(self):
+        if not self._dce_manager_uuid:
+            self._dce_manager_uuid = \
+                    self.simulation.create("DceManagerHelper")
+
+        return self._dce_manager_uuid
+
+    @property
+    def dce_application_uuid(self):
+        if not self._dce_application_uuid:
+            self._dce_application_uuid = \
+                    self.simulation.create("DceApplicationHelper")
+                        
+        return self._dce_application_uuid
+
+    @property
+    def dce_manager_lock(self):
+        return self._dce_manager_lock
+
+    @property
+    def dce_application_lock(self):
+        return self._dce_application_lock
+
index 0e5da2e..2c374ef 100644 (file)
@@ -185,7 +185,11 @@ class NS3BaseNode(NS3Base):
 
         container_uuid = self.simulation.create("NodeContainer")
         self.simulation.invoke(container_uuid, "Add", self.uuid)
-        with dceapp.dce_manager_lock:
-            self.simulation.invoke(dceapp.dce_manager_helper_uuid, 
-                    "Install", container_uuid)
+        
+        dce_helper = self.simulation.dce_helper
+
+        with dce_helper.dce_manager_lock:
+            dce_manager_uuid = dce_helper.dce_manager_uuid
+
+            self.simulation.invoke(dce_manager_uuid, "Install", container_uuid)