@@ -394,16 +394,28 @@ export class Connection extends DbgpConnection {
394394
395395 /** a counter for unique connection IDs */
396396 private static _connectionCounter = 1 ;
397+
397398 /** unique connection ID */
398399 public id : number ;
400+
399401 /** the time this connection was established */
400402 public timeEstablished : Date ;
401- /** a counter for unique transaction IDs */
402- private _transactionCounter = 0 ;
403+
404+ /** a counter for unique transaction IDs. */
405+ private _transactionCounter = 1 ;
406+
403407 /** the promise that gets resolved once we receive the init packet */
404408 private _initPromise : Promise < InitPacket > ;
405- /** the currently pending command that has been sent to XDebug and is awaiting a response or null */
406- private _pendingCommand : Command ;
409+
410+ /** resolves the init promise */
411+ private _initPromiseResolveFn : ( initPackt : InitPacket ) => any ;
412+
413+ /**
414+ * a map from transaction IDs to pending commands that have been sent to XDebug and are awaiting a response.
415+ * This should in theory only contain max one element at any time.
416+ */
417+ private _pendingCommands = new Map < number , Command > ( ) ;
418+
407419 /**
408420 * XDebug does NOT support async communication.
409421 * This means before sending a new command, we have to wait until we get a response for the previous.
@@ -417,13 +429,7 @@ export class Connection extends DbgpConnection {
417429 this . id = Connection . _connectionCounter ++ ;
418430 this . timeEstablished = new Date ( ) ;
419431 this . _initPromise = new Promise < InitPacket > ( ( resolve , reject ) => {
420- this . _pendingCommand = {
421- name : null ,
422- rejectFn : reject ,
423- resolveFn : ( document : XMLDocument ) => {
424- resolve ( new InitPacket ( document , this ) ) ;
425- }
426- } ;
432+ this . _initPromiseResolveFn = resolve ;
427433 } ) ;
428434 console . log ( 'New XDebug Connection #' + this . id ) ;
429435 }
@@ -438,18 +444,19 @@ export class Connection extends DbgpConnection {
438444 * After that, the next command in the queue is executed (if there is any).
439445 */
440446 protected handleResponse ( response : XMLDocument ) : void {
441- // XDebug sent us a packet
442- // Anatomy: [data length] [NULL] [xml] [NULL]
443- const command = this . _pendingCommand ;
444- if ( ! command ) {
445- console . error ( 'XDebug sent a response, but there was no pending command' ) ;
446- return ;
447- }
448- this . _pendingCommand = null ;
449- command . resolveFn ( response ) ;
450- if ( this . _commandQueue . length > 0 ) {
451- const command = this . _commandQueue . shift ( ) ;
452- this . _executeCommand ( command ) ;
447+ if ( response . documentElement . nodeName === 'init' ) {
448+ this . _initPromiseResolveFn ( new InitPacket ( response , this ) ) ;
449+ } else {
450+ const transactionId = parseInt ( response . documentElement . getAttribute ( 'transaction_id' ) ) ;
451+ if ( this . _pendingCommands . has ( transactionId ) ) {
452+ const command = this . _pendingCommands . get ( transactionId ) ;
453+ this . _pendingCommands . delete ( transactionId ) ;
454+ command . resolveFn ( response ) ;
455+ }
456+ if ( this . _commandQueue . length > 0 ) {
457+ const command = this . _commandQueue . shift ( ) ;
458+ this . _executeCommand ( command ) ;
459+ }
453460 }
454461 }
455462
@@ -461,7 +468,7 @@ export class Connection extends DbgpConnection {
461468 private _enqueueCommand ( name : string , args ?: string , data ?: string ) : Promise < XMLDocument > {
462469 return new Promise ( ( resolveFn , rejectFn ) => {
463470 const command = { name, args, data, resolveFn, rejectFn} ;
464- if ( this . _commandQueue . length === 0 && ! this . _pendingCommand ) {
471+ if ( this . _commandQueue . length === 0 && this . _pendingCommands . size === 0 ) {
465472 this . _executeCommand ( command ) ;
466473 } else {
467474 this . _commandQueue . push ( command ) ;
@@ -486,7 +493,7 @@ export class Connection extends DbgpConnection {
486493 commandString += '\0' ;
487494 const data = iconv . encode ( commandString , ENCODING ) ;
488495 this . write ( data ) ;
489- this . _pendingCommand = command ;
496+ this . _pendingCommands . set ( transactionId , command ) ;
490497 }
491498
492499 // ------------------------ status --------------------------------------------
0 commit comments