@@ -131,8 +131,9 @@ def is_waiting_for_connection(self):
131131 return self .is_waiting
132132
133133 def disconnect (self ):
134- self .sock .close ()
135- self .sock = None
134+ if self .sock is not None :
135+ self .sock .close ()
136+ self .sock = None
136137
137138 def stop (self ):
138139 self .action = 'stop'
@@ -188,6 +189,21 @@ def evaluate_expression(self, index, expression):
188189 self .start ()
189190
190191 def __connect_server (self ):
192+ """Connect to a server
193+
194+ We listen to incomming connections and at the same time try
195+ to distinguish two different things.
196+
197+ First, if a connection is accepted, see if we are interested
198+ in it at all by checking if our idekey matches with what
199+ xdebug sent us back. If the idekeys match, return the init
200+ message and carry on. If the idekeys do not match, discard
201+ the socket and continue listening to other incomming connections.
202+
203+ Second, while waiting for a connection to be accepted, also
204+ check did the user requested for canceling the connection to
205+ the server by unsetting the wait_for_accept flag.
206+ """
191207 socket_server = socket .socket (socket .AF_INET , socket .SOCK_STREAM )
192208 socket_server .setsockopt (socket .SOL_SOCKET , socket .SO_REUSEADDR , 1 )
193209 socket_server .settimeout (1 )
@@ -200,30 +216,39 @@ def __connect_server(self):
200216 port_number = int (get_setting ('debugger/port_number' ))
201217
202218 try :
203- # As long as the wait_for_accept flag is set
204- # try accepting the socket
205- # if the wait_for_accept flag is unset
206- # it means a cancel connection was requested
207219 socket_server .bind ((host , port_number ))
208220 socket_server .listen (5 )
209221
210- response = False
211-
212- while response is False :
222+ while response is None :
223+ # As long as the wait_for_accept flag is set
224+ # try accepting the socket
225+ # if the wait_for_accept flag is unset
226+ # it means a cancel connection was requested
213227 while self .wait_for_accept :
214228 try :
215229 self .sock , address = socket_server .accept ()
216230 self .sock .settimeout (None )
217- self .wait_for_accept = False
231+ # If we accepted a socket, break out of the inner
232+ # while loop, so we can check if we are accepting
233+ # for the current idekey
234+ if self .sock is not None :
235+ break
218236 except socket .timeout :
219237 pass
220- self .is_waiting = False
221- response = self .__init_connection ()
222238
223- if response is False :
224- self .sock .close ()
239+ try :
240+ response = self .__init_connection ()
241+ except RuntimeError :
242+ break
243+
244+ # Probably got a response but for a different idekey
245+ # discard socket and continue waiting for a connection
246+ if response is None :
247+ self .disconnect ()
225248 self .wait_for_accept = True
226- self .is_waiting = True
249+ else :
250+ self .wait_for_accept = False
251+ self .is_waiting = False
227252
228253 except OSError :
229254 print (OSError .strerror ())
@@ -234,6 +259,18 @@ def __connect_server(self):
234259 return response
235260
236261 def __init_connection (self ):
262+ """Init the connection with the debugger
263+
264+ Receives the init message from the debugger.
265+
266+ Sets features for max_depth, max_children and
267+ max_data.
268+
269+ If an init message is received, but has a different
270+ idekey than what we set, returns None.
271+
272+ Otherwise returns the init message.
273+ """
237274 if self .sock is None :
238275 raise RuntimeError ("Can't init connection without a socket" )
239276
@@ -245,7 +282,7 @@ def __init_connection(self):
245282
246283 # See if the init message from xdebug is meant for us
247284 if idekey != '' and init_message ['idekey' ] != idekey :
248- return False
285+ return None
249286
250287 command = 'feature_set -i %d -n max_depth -v 9' % (
251288 self .__get_transaction_id ()
0 commit comments