VirtualBox

Ignore:
Timestamp:
Feb 20, 2008 11:54:09 AM (17 years ago)
Author:
vboxsync
Message:

XPCOM/IPC: Made IPC_AddName()/IPC_RemoveName(), IPC_DefineTarget() to return a failure when the name/target is already defined or when a non-existent name/target is requested for removal.

File:
1 edited

Legend:

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

    r5522 r7029  
    8484  // the message observer is called via this event queue
    8585  nsCOMPtr<nsIEventQueue> eventQ;
    86  
     86
    8787  // incoming messages are added to this list
    8888  ipcMessageQ pendingQ;
     
    138138/* ------------------------------------------------------------------------- */
    139139
    140 typedef nsRefPtrHashtable<nsIDHashKey, ipcTargetData> ipcTargetMap; 
     140typedef nsRefPtrHashtable<nsIDHashKey, ipcTargetData> ipcTargetMap;
    141141
    142142class ipcClientState
     
    152152
    153153  //
    154   // the monitor protects the targetMap and the connected and shutdown flags. 
     154  // the monitor protects the targetMap and the connected and shutdown flags.
    155155  //
    156156  // NOTE: we use a PRMonitor for this instead of a PRLock because we need
     
    165165
    166166  // our process's client id
    167   PRUint32      selfID; 
     167  PRUint32      selfID;
    168168
    169169  nsCOMArray<ipcIClientObserver> clientObservers;
     
    319319
    320320  PRBool isIPCMTarget = aTarget.Equals(IPCM_TARGET);
    321  
     321
    322322  PRIntervalTime timeStart = PR_IntervalNow();
    323323  PRIntervalTime timeEnd;
     
    342342  // only the ICPM target is allowed to wait for a message after shutdown
    343343  // (but before disconnection).  this gives client observers called from
    344   // IPC_Shutdown a chance to use IPC_SendMessage to send necessary 
     344  // IPC_Shutdown a chance to use IPC_SendMessage to send necessary
    345345  // "last minute" messages to other clients.
    346  
     346
    347347  while (gClientState->connected && (!gClientState->shutdown || isIPCMTarget))
    348348  {
     
    375375      // to guarantee that every message is processed only once.
    376376      //
    377        
     377
    378378      if (!lastChecked->TestFlag(IPC_MSG_FLAG_IN_PROCESS))
    379379      {
     
    381381        PRBool accepted = (aSelector)(aArg, td, lastChecked);
    382382        lastChecked->ClearFlag(IPC_MSG_FLAG_IN_PROCESS);
    383        
     383
    384384        if (accepted)
    385385        {
     
    399399      lastChecked = lastChecked->mNext;
    400400    }
    401      
     401
    402402    if (*aMsg)
    403403    {
     
    517517CallProcessPendingQ(const nsID &target, ipcTargetData *td)
    518518{
    519   // we assume that we are inside td's monitor 
     519  // we assume that we are inside td's monitor
    520520
    521521  PLEvent *ev = new ipcEvent_ProcessPendingQ(target);
     
    562562/* ------------------------------------------------------------------------- */
    563563
     564// converts IPCM_ERROR_* status codes to NS_ERROR_* status codes
     565static nsresult nsresult_from_ipcm_result(PRInt32 status)
     566{
     567  nsresult rv = NS_ERROR_FAILURE;
     568
     569  switch (status)
     570  {
     571    case IPCM_ERROR_GENERIC:        rv = NS_ERROR_FAILURE; break;
     572    case IPCM_ERROR_INVALID_ARG:    rv = NS_ERROR_INVALID_ARG; break;
     573    // TODO: select better mapping for the below codes
     574    case IPCM_ERROR_NO_CLIENT:
     575    case IPCM_ERROR_NO_SUCH_DATA:
     576    case IPCM_ERROR_ALREADY_EXISTS: rv = NS_ERROR_FAILURE; break;
     577    default:                        NS_ASSERTION(PR_FALSE, "No conversion");
     578  }
     579
     580  return rv;
     581}
     582
     583/* ------------------------------------------------------------------------- */
     584
    564585// selects the next IPCM message with matching request index
    565586static PRBool
     
    571592
    572593// wait for an IPCM response message.  if responseMsg is null, then it is
    573 // assumed that the caller does not care to get a reference to the 
     594// assumed that the caller does not care to get a reference to the
    574595// response itself.  if the response is an IPCM_MSG_ACK_RESULT, then the
    575596// status code is mapped to a nsresult and returned by this function.
     
    588609    ipcMessageCast<ipcmMessageResult> result(msg);
    589610    if (result->Status() < 0)
    590       rv = NS_ERROR_FAILURE; // XXX nsresult_from_ipcm_result()
     611      rv = nsresult_from_ipcm_result(result->Status());
    591612    else
    592613      rv = NS_OK;
     
    682703  if (NS_FAILED(rv))
    683704    return rv;
    684  
     705
    685706  rv = IPC_Connect(dpath.get());
    686707  if (NS_FAILED(rv))
     
    742763
    743764  LOG(("IPC_Shutdown: connected=%d\n",gClientState->connected));
    744  
     765
    745766  if (gClientState->connected)
    746767  {
     
    748769      // first, set the shutdown flag and unblock any calls to WaitTarget.
    749770      // all targets but IPCM will not be able to use WaitTarget any more.
    750      
     771
    751772      nsAutoMonitor mon(gClientState->monitor);
    752773      gClientState->shutdown = PR_TRUE;
     
    759780    // (this is essential for the DConnect extension, for example, to do the
    760781    // proper uninitialization).
    761    
     782
    762783    ipcEvent_ClientState *ev = new ipcEvent_ClientState(IPC_SENDER_ANY,
    763784                                                        IPCM_CLIENT_STATE_DOWN);
    764785    ipcEvent_ClientState::HandleEvent (ev);
    765786    ipcEvent_ClientState::DestroyEvent (ev);
    766    
     787
    767788    IPC_Disconnect();
    768789  }
     
    896917  // process the specially forwarded client state message to see if the
    897918  // sender we're waiting a message from has died.
    898  
     919
    899920  if (msg->Target().Equals(IPCM_TARGET))
    900921  {
     
    910931          LOG(("sender (%d) we're waiting a message from (%d) has died\n",
    911932               status->ClientID(), data->senderID));
    912                
     933
    913934          if (data->senderID != IPC_SENDER_ANY)
    914935          {
    915936            // we're waiting on a particular client, so IPC_WaitMessage must
    916937            // definitely fail with the NS_ERROR_xxx result.
    917            
     938
    918939            data->senderDead = PR_TRUE;
    919940            return PR_TRUE; // consume the message
     
    929950              obs = td->observer;
    930951            NS_ASSERTION(obs, "must at least have a default observer");
    931            
     952
    932953            nsresult rv = obs->OnMessageAvailable(status->ClientID(), nsID(), 0, 0);
    933954            if (rv != IPC_WAIT_NEXT_MESSAGE)
     
    9861007  if (NS_FAILED(rv))
    9871008    return rv;
    988  
     1009
    9891010  // if the requested sender has died while waiting, return an error
    9901011  if (data.senderDead)
    9911012    return NS_ERROR_ABORT; // XXX better error code?
    992  
     1013
    9931014  // if the selector has accepted some message, then we pass it to aConsumer
    9941015  // for safe processing.  The IPC susbsystem is quite stable here (i.e. we're
     
    10021023                                  msg->DataLen());
    10031024  }
    1004  
     1025
    10051026  delete msg;
    10061027
     
    10811102    rv = NS_ERROR_UNEXPECTED;
    10821103  }
    1083    
     1104
    10841105  delete msg;
    10851106  return rv;
     
    12251246    PlaceOnPendingQ(aKey, aData, msg->Clone());
    12261247  }
    1227  
     1248
    12281249  return PL_DHASH_NEXT;
    12291250}
     
    12761297        PostEventToMainThread(new ipcEvent_ClientState(status->ClientID(),
    12771298                                                       status->ClientState()));
    1278        
     1299
    12791300        // go through the target map, and place this message to every target's
    12801301        // pending event queue.  that unblocks all WaitTarget calls (on all
     
    12851306
    12861307        delete msg;
    1287        
     1308
    12881309        return;
    12891310      }
     
    12951316  {
    12961317    // make copy of target since |msg| may end up pointing to free'd memory
    1297     // once we notify the monitor inside PlaceOnPendingQ(). 
     1318    // once we notify the monitor inside PlaceOnPendingQ().
    12981319    const nsID target = msg->Target();
    1299    
     1320
    13001321    PlaceOnPendingQ(target, td, msg);
    13011322  }
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