[Pysnmp-dev] More potential socket_map issues
Brought to you by:
elie
From: Mark M E. <mar...@ma...> - 2007-08-27 03:27:57
|
First of all, in case I haven't mentioned it already, I'm really impressed by PySNMP. I think it is an amazing piece of work. Also, I'm new to PySNMP and SNMP, so I'm still learning my way around. 4.1.9a (aka CVS) fixes the socket leak, but it's still creating "side effects" in the asyncore.socket_map. Consider the following code: ===========================8<============================== from pysnmp.carrier.asynsock import dispatch from pysnmp.entity import engine from pysnmp.entity.rfc3413.oneliner import cmdgen security_name = 'default' community_name = 'xxx' address = '10.0.1.1' # My Airport Extreme Wireless router port = 161 # iso.org.dod.internet.private.enterprises.apple.airport.baseStation3. # physicalInterfaces.physicalInterfacesTable.physicalInterface. # physicalInterfaceNumRX.1 object_name = (1, 3, 6, 1, 4, 1, 63, 501, 3, 4, 2, 1, 8, 1) auth_data = cmdgen.CommunityData(security_name, community_name, 1) transportTarget = cmdgen.UdpTransportTarget((address, port)) snmpEngine = engine.SnmpEngine() transportDispatcher = dispatch.AsynsockDispatcher() transportDispatcher.setSocketMap({}) snmpEngine.registerTransportDispatcher(transportDispatcher) errorIndication, errorStatus, errorIndex, varBinds = ( cmdgen.CommandGenerator(snmpEngine).getCmd( auth_data, transportTarget, object_name ) ) ===========================>8============================== In so far as this creates a blocking command that uses it's own socket map in runDispatcher(), this works great. But internally, the transport is being added initially to the asyncore.socket_map and then it is also being added the the __sockMap of the transportDispatcher. I'm concerned about the transport ever being added to asyncore.socket_map when it is being created for an transportDispatcher that has it's own map. The reason that I'm concerned is that I'm trying to make sure that I can invoke a blocking command in a thread without effecting some other package that is using asyncore in another thread (like Medussa). Although my example is using blocking commands, I think that any attempt to use a non-default socket map will result in the same behavior. It seems like the correct socket map is explicitly managed via registerTransport() and unregisterTransport(). Therefore it seems like a AbstractSocketTransport should not implicitly added to asyncore.socket_map, but rather defer that decision until registerTransport() is called. The following worked for me (similar to my original hack, but closer to the source of the problem): class AbstractSocketTransport(asyncore.dispatcher): sockFamily = sockType = None retryCount = 0; retryInterval = 0 def __init__(self, sock=None, sockMap=None): # @patch begin # The socket map is managed by the AsynsockDispatcher on which this # transport is registered. if sockMap is None: sockMap = {} # @patch end if sock is None: try: The temporary socket map is immediately discarded and then the AbstractSocketTransport only participates in the socket map of the AsynsockDispatcher on which it is registered. Hopefully what I've said made sense. Regards, Mark |