PyNDN: A lot of fixes and API unification
There is actually a very strange/interesting bug with callback
Python/C++/Python callback mechanism. Needed to add a nasty addition
(potential memory leak and performance degradation) to eliminate
segfaults.
diff --git a/PyNDN/Face.py b/PyNDN/Face.py
index 3f76f5d..3a905fa 100644
--- a/PyNDN/Face.py
+++ b/PyNDN/Face.py
@@ -24,8 +24,11 @@
from Interest import Interest
from Name import Name
+import time
import functools
+deleteList = []
+
class Face (ns.ndnSIM.ndn.ApiFace):
def __init__(self):
self.nodeId = ns.core.Simulator.GetContext ()
@@ -41,6 +44,7 @@
def defer_verification (self, deferVerification = True):
pass
+
def expressInterest (self, name, onData, onTimeout, template = None):
"""
onData: void <interest, name>
@@ -50,34 +54,16 @@
interest = Interest (interest = template)
interest.name = name
- class OnDataConvert:
- def __init__ (self, onData):
- self.onData = onData
- def __call__ (self, interest, data):
- if self.onData:
- return self.onData (Interest (interest=interest), Data (data = data))
+ converter = ExpressInterestConverter (onData, onTimeout)
+ deleteList.append (converter)
- class OnTimeoutConvert:
- def __init__ (self, onTimeout):
- self.onTimeout = onTimeout
- def __call__ (self, interest):
- if self.onTimeout:
- self.onTimeout (Interest (interest=interest))
-
- self.ExpressInterest (interest._interest, OnDataConvert (onData), OnTimeoutConvert (onTimeout))
+ self.ExpressInterest (interest._interest, converter.handleOnData, converter.handleOnTimeout)
def setInterestFilter (self, name, onInterest, flags = None):
"""
onInterest: void <name, interest>
"""
- class OnInterestConvert:
- def __init__ (self, onInterest):
- self.onInterest = onInterest
- def __call__ (self, name, interest):
- if self.onInterest:
- self.onInterest (Name (name = name), Interest (interest = interest))
-
if isinstance (name, Name):
name = name._name
elif isinstance (name, ns.ndnSIM.ndn.Name):
@@ -85,7 +71,10 @@
else:
raise TypeError ("Wrong type for 'name' parameter [%s]" % type (name))
- self.SetInterestFilter (name, OnInterestConvert (onInterest))
+ converter = OnInterestConvert (onInterest)
+ deleteList.append (converter)
+
+ self.SetInterestFilter (name, converter)
def clearInterestFilter (self, name):
if isinstance (name, Name):
@@ -95,10 +84,42 @@
else:
raise TypeError ("Wrong type for 'name' parameter [%s]" % type (name))
+ # @bug: memory leak, deleteList need to remove previosly set callback... but how?
self.ClearInterestFilter (name)
def get (self, name, template = None, timeoutms = 3000):
raise NotImplementedError ("NS-3 simulation cannot have syncrhonous operations")
def put (self, data):
- self.Put (data)
+ if isinstance (data, Data):
+ self.Put (data._data)
+ elif isinstance (data, ns.ndnSIM.ndn.Data):
+ self.Put (data)
+ else:
+ raise TypeError ("Unsupported type to publish data [%s]" % type (data))
+
+def removeFromDeleteList (object):
+ deleteList.remove (object)
+
+class ExpressInterestConverter:
+ def __init__ (self, onData, onTimeout):
+ self.onData = onData
+ self.onTimeout = onTimeout
+
+ def handleOnData (self, interest, data):
+ ns.core.Simulator.ScheduleNow (removeFromDeleteList, self)
+ if self.onData:
+ return self.onData (Interest (interest=interest), Data (data = data))
+
+ def handleOnTimeout (self, interest):
+ ns.core.Simulator.ScheduleNow (removeFromDeleteList, self)
+ if self.onTimeout:
+ self.onTimeout (Interest (interest=interest))
+
+class OnInterestConvert (object):
+ def __init__ (self, onInterest):
+ self.onInterest = onInterest
+ def __call__ (self, name, interest):
+ ns.core.Simulator.ScheduleNow (removeFromDeleteList, self)
+ if self.onInterest:
+ self.onInterest (Name (name = name), Interest (interest = interest))