VirtualBox

Changeset 7029 in vbox for trunk/src/libs/xpcom18a4


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.

Location:
trunk/src/libs/xpcom18a4/ipc/ipcd
Files:
7 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  }
  • trunk/src/libs/xpcom18a4/ipc/ipcd/daemon/src/ipcClient.cpp

    r1 r7029  
    9696}
    9797
    98 void
     98PRBool
    9999ipcClient::DelName(const char *name)
    100100{
    101101    LOG(("deleting client name: %s\n", name));
    102102
    103     mNames.FindAndDelete(name);
     103    return mNames.FindAndDelete(name);
    104104}
    105105
     
    115115}
    116116
    117 void
     117PRBool
    118118ipcClient::DelTarget(const nsID &target)
    119119{
     
    124124    //
    125125    if (!target.Equals(IPCM_TARGET))
    126         mTargets.FindAndDelete(target);
     126        return mTargets.FindAndDelete(target);
     127
     128    return PR_FALSE;
    127129}
    128130
     
    185187        }
    186188    }
    187  
     189
    188190    if (inFlags & PR_POLL_WRITE) {
    189191        LOG(("client socket is now writable\n"));
  • trunk/src/libs/xpcom18a4/ipc/ipcd/daemon/src/ipcClient.h

    r1 r7029  
    6565
    6666    void   AddName(const char *name);
    67     void  DelName(const char *name);
     67    PRBool DelName(const char *name);
    6868    PRBool HasName(const char *name) const { return mNames.Find(name) != NULL; }
    6969
    7070    void   AddTarget(const nsID &target);
    71     void  DelTarget(const nsID &target);
     71    PRBool DelTarget(const nsID &target);
    7272    PRBool HasTarget(const nsID &target) const { return mTargets.Find(target) != NULL; }
    7373
     
    9696    //
    9797    // returns:
    98     //   0             - to cancel client connection 
     98    //   0             - to cancel client connection
    9999    //   PR_POLL_READ  - to poll for a readable socket
    100100    //   PR_POLL_WRITE - to poll for a writable socket
     
    102102    //
    103103    // the socket is non-blocking.
    104     // 
     104    //
    105105    int Process(PRFileDesc *sockFD, int pollFlags);
    106106
     
    125125    // encoded in it.
    126126    PRUint32      mPID;
    127    
     127
    128128    // the hwnd of the client's message window.
    129129    HWND          mHwnd;
  • trunk/src/libs/xpcom18a4/ipc/ipcd/daemon/src/ipcCommandModule.cpp

    r1 r7029  
    6262
    6363        const ipcStringNode *node;
    64        
     64
    6565        for (node = nodes; node; node = node->mNext)
    6666            count++;
     
    8484
    8585        const ipcIDNode *node;
    86        
     86
    8787        for (node = nodes; node; node = node->mNext)
    8888            count++;
     
    133133        LOG(("got CLIENT_ADD_NAME\n"));
    134134
     135        PRInt32 status = IPCM_OK;
     136        PRUint32 requestIndex = IPCM_GetRequestIndex(rawMsg);
     137
    135138        ipcMessageCast<ipcmMessageClientAddName> msg(rawMsg);
    136139        const char *name = msg->Name();
    137         if (name)
    138             client->AddName(name);
    139 
    140         // TODO: send better status code (e.g., suppose name already defined for client)
    141         IPC_SendMsg(client, new ipcmMessageResult(IPCM_GetRequestIndex(rawMsg), IPCM_OK));
     140        if (name) {
     141            ipcClient *result = IPC_GetClientByName(msg->Name());
     142            if (result) {
     143                LOG(("  client with such name already exists (ID = %d)\n", result->ID()));
     144                status = IPCM_ERROR_ALREADY_EXISTS;
     145            }
     146            else
     147                client->AddName(name);
     148        }
     149        else
     150            status = IPCM_ERROR_INVALID_ARG;
     151
     152        IPC_SendMsg(client, new ipcmMessageResult(requestIndex, status));
    142153    }
    143154
     
    146157    {
    147158        LOG(("got CLIENT_DEL_NAME\n"));
     159
     160        PRInt32 status = IPCM_OK;
     161        PRUint32 requestIndex = IPCM_GetRequestIndex(rawMsg);
    148162
    149163        ipcMessageCast<ipcmMessageClientDelName> msg(rawMsg);
    150164        const char *name = msg->Name();
    151         if (name)
    152             client->DelName(name);
    153 
    154         // TODO: send better status code (e.g., suppose name not defined for client)
    155         IPC_SendMsg(client, new ipcmMessageResult(IPCM_GetRequestIndex(rawMsg), IPCM_OK));
     165        if (name) {
     166            if (!client->DelName(name)) {
     167                LOG(("  client doesn't have name '%s'\n", name));
     168                status = IPCM_ERROR_NO_SUCH_DATA;
     169            }
     170        }
     171        else
     172            status = IPCM_ERROR_INVALID_ARG;
     173
     174        IPC_SendMsg(client, new ipcmMessageResult(requestIndex, status));
    156175    }
    157176
     
    161180        LOG(("got CLIENT_ADD_TARGET\n"));
    162181
     182        PRInt32 status = IPCM_OK;
     183        PRUint32 requestIndex = IPCM_GetRequestIndex(rawMsg);
     184
    163185        ipcMessageCast<ipcmMessageClientAddTarget> msg(rawMsg);
    164         client->AddTarget(msg->Target());
    165 
    166         // TODO: send better status code (e.g., suppose target already defined for client)
    167         IPC_SendMsg(client, new ipcmMessageResult(IPCM_GetRequestIndex(rawMsg), IPCM_OK));
     186        if (client->HasTarget(msg->Target())) {
     187            LOG(("  target already defined for client\n"));
     188            status = IPCM_ERROR_ALREADY_EXISTS;
     189        }
     190        else
     191            client->AddTarget(msg->Target());
     192
     193        IPC_SendMsg(client, new ipcmMessageResult(requestIndex, status));
    168194    }
    169195
     
    173199        LOG(("got CLIENT_DEL_TARGET\n"));
    174200
     201        PRInt32 status = IPCM_OK;
     202        PRUint32 requestIndex = IPCM_GetRequestIndex(rawMsg);
     203
    175204        ipcMessageCast<ipcmMessageClientDelTarget> msg(rawMsg);
    176         client->DelTarget(msg->Target());
    177 
    178         // TODO: send better status code (e.g., suppose target not defined for client)
    179         IPC_SendMsg(client, new ipcmMessageResult(IPCM_GetRequestIndex(rawMsg), IPCM_OK));
     205        if (!client->DelTarget(msg->Target())) {
     206            LOG(("  client doesn't have the given target\n"));
     207            status = IPCM_ERROR_NO_SUCH_DATA;
     208        }
     209
     210        IPC_SendMsg(client, new ipcmMessageResult(requestIndex, status));
    180211    }
    181212
     
    222253        else {
    223254            LOG(("  client does not exist\n"));
    224             IPC_SendMsg(client, new ipcmMessageError(IPCM_ERROR_CLIENT_NOT_FOUND, msg->RequestIndex()));
     255            IPC_SendMsg(client, new ipcmMessageError(IPCM_ERROR_NO_CLIENT, msg->RequestIndex()));
    225256        }
    226257    }
     
    278309    type--;
    279310    if (type < 0 || type >= (int) (sizeof(handlers)/sizeof(handlers[0]))) {
    280         LOG(("unknown request -- ignoring message\n")); 
     311        LOG(("unknown request -- ignoring message\n"));
    281312        return;
    282313    }
  • trunk/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcIDList.h

    r1 r7029  
    8686    }
    8787
    88     void FindAndDelete(const nsID &id)
     88    PRBool FindAndDelete(const nsID &id)
    8989    {
    9090        ipcIDNode *node = FindNodeBefore(mHead, id);
    91         if (node)
     91        if (node) {
    9292            DeleteAfter(node);
    93         else
     93            return PR_TRUE;
     94        }
     95        else if (!IsEmpty()) {
    9496            DeleteFirst();
     97            return PR_TRUE;
     98        }
     99
     100        return PR_FALSE;
    95101    }
    96102
  • trunk/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcStringList.h

    r1 r7029  
    9292    }
    9393
    94     void FindAndDelete(const char *str)
     94    PRBool FindAndDelete(const char *str)
    9595    {
    9696        ipcStringNode *node = FindNodeBefore(mHead, str);
    97         if (node)
     97        if (node) {
    9898            DeleteAfter(node);
    99         else
     99            return PR_TRUE;
     100        }
     101        else if (!IsEmpty()) {
    100102            DeleteFirst();
     103            return PR_TRUE;
     104        }
     105
     106        return PR_FALSE;
    101107    }
    102108
  • trunk/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcm.h

    r1 r7029  
    129129
    130130//
    131 // return IPCM message request index. 
     131// return IPCM message request index.
    132132//
    133133static inline PRUint32
     
    258258// This request message has as its payload a null-terminated ASCII character
    259259// string indicating the client name to query.
    260 // 
     260//
    261261
    262262// ACKNOWLEDGEMENTS
     
    272272// codes):
    273273//
    274 #define IPCM_OK               0  // success: generic
    275 #define IPCM_ERROR_GENERIC   -1  // failure: generic
    276 #define IPCM_ERROR_NO_CLIENT -2  // failure: client does not exist
     274#define IPCM_OK                      0  // success: generic
     275#define IPCM_ERROR_GENERIC          -1  // failure: generic
     276#define IPCM_ERROR_NO_CLIENT        -2  // failure: client does not exist
     277#define IPCM_ERROR_INVALID_ARG      -3  // failure: invalid request argument
     278#define IPCM_ERROR_NO_SUCH_DATA     -4  // failure: requested data does not exist
     279#define IPCM_ERROR_ALREADY_EXISTS   -5  // failure: data to set already exists
    277280
    278281//
     
    310313// This message is sent by the daemon to a client on behalf of another client.
    311314// The recipient is expected to unpack the contained message and process it.
    312 // 
     315//
    313316// The payload of this message matches the payload of IPCM_MSG_REQ_FORWARD,
    314317// with the exception that the clientID field is set to the clientID of the
     
    323326//       adds no additional member variables.  |operator new| should be used
    324327//       to allocate one of the IPCM helper classes, e.g.:
    325 //         
     328//
    326329//          ipcMessage *msg = new ipcmMessageClientHello("foo");
    327330//
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