VirtualBox

Changeset 103055 in vbox for trunk/src/libs


Ignore:
Timestamp:
Jan 25, 2024 10:03:13 AM (12 months ago)
Author:
vboxsync
Message:

libs/xpcom/ipcd: Fix regression introduced with r160171.

With r160171 the IPC client array is not compact anymore but can contain holes
due to the index being used as the pollset identifier for faster access.
Some functions in ipcd.cpp however use the current client count and traverse the
client array for some messages (broadcasts, client up, client down, etc.).
This doesn't work with holes in the array if a client spawned before another one
is shut down, so all later clients wouldn't receive those messages anymore.
Fix this exposing a doubly linked list of clients which allows to traverse all
connected clients without having to use the client connection counter.

Location:
trunk/src/libs/xpcom18a4/ipc/ipcd/daemon/src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/libs/xpcom18a4/ipc/ipcd/daemon/src/ipcClient.h

    r102062 r103055  
    3939#define ipcClientUnix_h__
    4040
     41#include <iprt/list.h>
    4142#include <iprt/socket.h>
    4243
     
    5657{
    5758public:
     59    /** Node for the list of clients. */
     60    RTLISTNODE NdClients;
    5861    bool     m_fUsed;
    5962    uint32_t m_idPoll;
  • trunk/src/libs/xpcom18a4/ipc/ipcd/daemon/src/ipcd.cpp

    r102249 r103055  
    104104        // broadcast
    105105        //
    106         for (int i=0; i<ipcClientCount; ++i)
    107             IPC_SendMsg(&ipcClients[i], msg->Clone());
     106        ipcClient *pIt;
     107        RTListForEachCpp(&g_LstIpcClients, pIt, ipcClient, NdClients)
     108        {
     109            IPC_SendMsg(pIt, msg->Clone());
     110        }
    108111        delete msg;
    109112        return PR_SUCCESS;
     
    128131    Log(("IPC_NotifyClientUp: clientID=%d\n", client->ID()));
    129132
    130     for (int i=0; i<ipcClientCount; ++i) {
    131         if (&ipcClients[i] != client)
    132             IPC_SendMsg(&ipcClients[i],
     133    ipcClient *pIt;
     134    RTListForEachCpp(&g_LstIpcClients, pIt, ipcClient, NdClients)
     135    {
     136        if (pIt != client)
     137            IPC_SendMsg(pIt,
    133138                new ipcmMessageClientState(client->ID(), IPCM_CLIENT_STATE_UP));
    134139    }
     
    140145    Log(("IPC_NotifyClientDown: clientID=%d\n", client->ID()));
    141146
    142     for (int i=0; i<ipcClientCount; ++i) {
    143         if (&ipcClients[i] != client)
    144             IPC_SendMsg(&ipcClients[i],
     147    ipcClient *pIt;
     148    RTListForEachCpp(&g_LstIpcClients, pIt, ipcClient, NdClients)
     149    {
     150        if (pIt != client)
     151            IPC_SendMsg(pIt,
    145152                new ipcmMessageClientState(client->ID(), IPCM_CLIENT_STATE_DOWN));
    146153    }
     
    161168{
    162169    // linear search OK since number of clients should be small
    163     for (int i = 0; i < ipcClientCount; ++i) {
    164         if (ipcClients[i].ID() == clientID)
    165             return &ipcClients[i];
     170    ipcClient *pIt;
     171    RTListForEachCpp(&g_LstIpcClients, pIt, ipcClient, NdClients)
     172    {
     173        if (pIt->ID() == clientID)
     174            return pIt;
    166175    }
    167176    return NULL;
     
    172181{
    173182    // linear search OK since number of clients should be small
    174     for (int i = 0; i < ipcClientCount; ++i) {
    175         if (ipcClients[i].HasName(name))
    176             return &ipcClients[i];
     183    ipcClient *pIt;
     184    RTListForEachCpp(&g_LstIpcClients, pIt, ipcClient, NdClients)
     185    {
     186        if (pIt->HasName(name))
     187            return pIt;
    177188    }
    178189    return NULL;
     
    183194{
    184195    Assert(func);
    185     for (int i = 0; i < ipcClientCount; ++i) {
    186         if (func(closure, &ipcClients[i], ipcClients[i].ID()) == PR_FALSE)
     196    ipcClient *pIt;
     197    RTListForEachCpp(&g_LstIpcClients, pIt, ipcClient, NdClients)
     198    {
     199        if (func(closure, pIt, pIt->ID()) == PR_FALSE)
    187200            break;
    188201    }
  • trunk/src/libs/xpcom18a4/ipc/ipcd/daemon/src/ipcdPrivate.h

    r102047 r103055  
    3939#define ipcdPrivate_h__
    4040
     41#include <iprt/cdefs.h>
     42#include <iprt/list.h>
     43
    4144class ipcClient;
    4245
     
    4750#define IPC_MAX_CLIENTS 10000
    4851
    49 //
    50 // array of connected clients
    51 //
    52 extern ipcClient *ipcClients;
    53 extern int        ipcClientCount;
     52/** List of connected IPC clients. */
     53extern RTLISTANCHOR g_LstIpcClients;
    5454
    5555//
  • trunk/src/libs/xpcom18a4/ipc/ipcd/daemon/src/ipcdUnix.cpp

    r102345 r103055  
    265265// declared in ipcdPrivate.h
    266266//
    267 ipcClient *ipcClients = NULL;
    268 int        ipcClientCount = 0;
     267DECL_HIDDEN_DATA(RTLISTANCHOR) g_LstIpcClients;
     268static int                     ipcClientCount = 0;
    269269
    270270//
     
    296296            if (RT_SUCCESS(vrc))
    297297            {
     298                RTListAppend(&g_LstIpcClients, &ipcClientArray[i].NdClients);
    298299                ipcClientCount++;
    299300                return 0;
     
    314315    AssertRC(vrc); RT_NOREF(vrc);
    315316
     317    RTListNodeRemove(&ipcClientArray[idClient].NdClients);
    316318    ipcClientArray[idClient].Finalize();
    317319    --ipcClientCount;
     
    323325static void PollLoop(RTPOLLSET hPollSet, int fdListen)
    324326{
    325     ipcClients = ipcClientArray;
     327    RTListInit(&g_LstIpcClients);
    326328
    327329    for (;;)
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