VirtualBox

Changeset 30052 in vbox for trunk


Ignore:
Timestamp:
Jun 7, 2010 7:57:21 AM (15 years ago)
Author:
vboxsync
Message:

xpcom/ipcd: Fix message processing so that IPCM client up/down messages are not piled up in the dconnect message queue. Mainly involved converting the boolean wait/process message handling logic to a tri-state wait/process/discard style. The IPCM messages can now be processed without being passed to the DConnect message processing logic.

Location:
trunk/src/libs/xpcom18a4/ipc/ipcd/client
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/libs/xpcom18a4/ipc/ipcd/client/public/ipcdclient.h

    r1 r30052  
    6868  NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_GENERAL, 10)
    6969
     70#ifdef VBOX
     71/* This error code can only be returned by the selector functions called by
     72 * WaitTarget. The message should be dropped without processing. */
     73#define IPC_DISCARD_MESSAGE \
     74  NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_GENERAL, 12)
     75#endif /* VBOX */
     76
    7077/* This error code is returned by IPC_WaitMessage under certain conditions. */
    7178#define IPC_ERROR_WOULD_BLOCK NS_BASE_STREAM_WOULD_BLOCK
     
    99106 * the IPC_WaitMessage function, that will immediately fail with an error.
    100107 * OnClientStateChange is called on the same thread where this function is
    101  * called. 
     108 * called.
    102109 *
    103110 * @returns NS_ERROR_NOT_INITIALIZED if IPC_Init has not been called or if
  • trunk/src/libs/xpcom18a4/ipc/ipcd/client/src/ipcdclient.cpp

    r26582 r30052  
    289289// message target.  the selector is called while inside the target's monitor.
    290290
    291 typedef PRBool (* ipcMessageSelector)(
     291typedef nsresult (* ipcMessageSelector)(
    292292  void *arg,
    293293  ipcTargetData *td,
     
    296296
    297297// selects any
    298 static PRBool
     298static nsresult
    299299DefaultSelector(void *arg, ipcTargetData *td, const ipcMessage *msg)
    300300{
    301   return PR_TRUE;
     301  return NS_OK;
    302302}
    303303
     
    379379      {
    380380        lastChecked->SetFlag(IPC_MSG_FLAG_IN_PROCESS);
    381         PRBool accepted = (aSelector)(aArg, td, lastChecked);
     381        nsresult acceptedRV = (aSelector)(aArg, td, lastChecked);
    382382        lastChecked->ClearFlag(IPC_MSG_FLAG_IN_PROCESS);
    383383
    384         if (accepted)
     384        if (acceptedRV != IPC_WAIT_NEXT_MESSAGE)
    385385        {
    386386          // remove from pending queue
     
    389389          else
    390390            td->pendingQ.RemoveFirst();
    391           lastChecked->mNext = nsnull;
    392 
    393           *aMsg = lastChecked;
    394           break;
     391
     392          if (acceptedRV != IPC_DISCARD_MESSAGE)
     393          {
     394            lastChecked->mNext = nsnull;
     395            *aMsg = lastChecked;
     396            break;
     397          }
    395398        }
    396399      }
     
    411414       * This is necessary as there might be several threads waiting for
    412415       * a message from a single client, and only one gets the DOWN msg. */
    413       PRBool alive = (aSelector)(aArg, td, NULL);
    414       if (!alive)
     416      nsresult aliveRV = (aSelector)(aArg, td, NULL);
     417      if (aliveRV != IPC_WAIT_NEXT_MESSAGE)
    415418      {
    416419        *aMsg = NULL;
     
    598601
    599602// selects the next IPCM message with matching request index
    600 static PRBool
     603static nsresult
    601604WaitIPCMResponseSelector(void *arg, ipcTargetData *td, const ipcMessage *msg)
    602605{
    603606#ifdef VBOX
    604607  if (!msg)
    605     return PR_TRUE;
     608    return IPC_WAIT_NEXT_MESSAGE;
    606609#endif /* VBOX */
    607610  PRUint32 requestIndex = *(PRUint32 *) arg;
    608   return IPCM_GetRequestIndex(msg) == requestIndex;
     611  return IPCM_GetRequestIndex(msg) == requestIndex ? NS_OK : IPC_WAIT_NEXT_MESSAGE;
    609612}
    610613
     
    929932};
    930933
    931 static PRBool WaitMessageSelector(void *arg, ipcTargetData *td, const ipcMessage *msg)
     934static nsresult WaitMessageSelector(void *arg, ipcTargetData *td, const ipcMessage *msg)
    932935{
    933936  WaitMessageSelectorData *data = (WaitMessageSelectorData *) arg;
     
    944947    nsresult rv = obs->OnMessageAvailable(IPC_SENDER_ANY, nsID(), 0, 0);
    945948    if (rv != IPC_WAIT_NEXT_MESSAGE)
    946     {
    947949      data->senderDead = PR_TRUE;
    948       return PR_FALSE;
    949     }
    950     return PR_TRUE;
     950
     951    return rv;
    951952  }
    952953#endif /* VBOX */
     
    975976
    976977            data->senderDead = PR_TRUE;
    977             return PR_TRUE; // consume the message
     978            return IPC_DISCARD_MESSAGE; // consume the message
    978979          }
    979980          else
     
    990991            nsresult rv = obs->OnMessageAvailable(status->ClientID(), nsID(), 0, 0);
    991992            if (rv != IPC_WAIT_NEXT_MESSAGE)
    992             {
    993993              data->senderDead = PR_TRUE;
    994               return PR_TRUE; // consume the message
    995             }
     994
     995            return IPC_DISCARD_MESSAGE; // consume the message
    996996          }
    997997        }
     
    10191019             * this case. A client ID wraparound can't falsely trigger
    10201020             * this, since the waiting thread would have hit the liveness
    1021              * check in the mean time. Also, DO NOT consume the message,
    1022              * otherwise it gets passed to the DConnect message handling
    1023              * without any further checks. IPCM messages are automatically
    1024              * discarded if they are left unclaimed. */
     1021             * check in the mean time. We MUST consume the message, otherwise
     1022             * IPCM messages pile up as long as there is a pending call, which
     1023             * can lead to severe processing overhead. */
     1024            return IPC_DISCARD_MESSAGE; // consume the message
    10251025          }
    10261026        }
     
    10311031        NS_NOTREACHED("unexpected message");
    10321032    }
    1033     return PR_FALSE; // continue iterating
     1033    return IPC_WAIT_NEXT_MESSAGE; // continue iterating
    10341034  }
    10351035
     
    10511051
    10521052  // stop iterating if we got a match that the observer accepted.
    1053   return rv != IPC_WAIT_NEXT_MESSAGE;
     1053  return rv != IPC_WAIT_NEXT_MESSAGE ? NS_OK : IPC_WAIT_NEXT_MESSAGE;
    10541054}
    10551055
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette