VirtualBox

Changeset 103472 in vbox for trunk/src/libs/xpcom18a4/ipc


Ignore:
Timestamp:
Feb 20, 2024 9:26:18 AM (12 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
161808
Message:

libs/xpcom: Rewrite the IPC client side to reduce the number of memory allocations, bugref:10598

Location:
trunk/src/libs/xpcom18a4/ipc/ipcd
Files:
6 deleted
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/libs/xpcom18a4/ipc/ipcd/client/public/ipcIService.idl

    r1 r103472  
    118118     */
    119119    unsigned long resolveClientName(in string aName);
    120 
    121 
    122     /**
    123      * tests whether a particular client is connected to the IPC daemon.
    124      */
    125     boolean clientExists(in unsigned long aClientID);
    126120
    127121
  • trunk/src/libs/xpcom18a4/ipc/ipcd/client/public/ipcdclient.h

    r102470 r103472  
    291291);
    292292
    293 /**
    294  * Tests whether the client is connected to the IPC daemon.
    295  */
    296 IPC_METHOD IPC_ClientExists(
    297   PRUint32  aClientID,
    298   PRBool   *aResult
    299 );
    300 
    301293/*****************************************************************************/
    302294
  • trunk/src/libs/xpcom18a4/ipc/ipcd/client/src/ipcConnection.h

    r1 r103472  
    4040
    4141#include "nscore.h"
    42 
    43 class ipcMessage;
     42#include "ipcMessageNew.h"
    4443
    4544#define IPC_METHOD_PRIVATE_(type)   NS_HIDDEN_(type)
     
    8887 * NOTE: This function may be called on any thread.
    8988 */
    90 IPC_METHOD_PRIVATE IPC_SendMsg(ipcMessage *msg);
     89IPC_METHOD_PRIVATE IPC_SendMsg(PIPCMSG pMsg);
    9190
    9291/**
     
    140139 *
    141140 * This function is called whenever an incoming message is read from the IPC
    142  * daemon.  The ipcMessage object, |msg|, must be deleted by the implementation
    143  * of IPC_OnMessageAvailable when the object is no longer needed.
     141 * daemon.  The implementer of this method must not assume ownership over the
     142 * message.
    144143 */
    145 IPC_METHOD_PRIVATE_(void) IPC_OnMessageAvailable(ipcMessage *msg);
     144DECLHIDDEN(void) IPC_OnMessageAvailable(PCIPCMSG pMsg);
     145
     146/**
     147 * IPC_MsgFree
     148 *
     149 * This function is called whenever an outgoing message was sent by the
     150 * connection code and the message can be freed.
     151 */
     152DECLHIDDEN(void) IPC_MsgFree(PIPCMSG pMsg);
    146153
    147154#endif // ipcConnection_h__
  • trunk/src/libs/xpcom18a4/ipc/ipcd/client/src/ipcConnectionUnix.cpp

    r102060 r103472  
    3939#include <iprt/err.h>
    4040#include <iprt/env.h>
     41#include <iprt/list.h>
    4142#include <iprt/mem.h>
    4243#include <iprt/pipe.h>
     
    5758
    5859#include "ipcConnection.h"
    59 #include "ipcMessageQ.h"
     60#include "ipcMessageNew.h"
     61#include "ipcList.h"
    6062#include "ipcConfig.h"
    6163
     
    129131    RTPOLLSET    hPollSet;
    130132    ipcCallbackQ callback_queue;
    131     ipcMessageQ  send_queue;
    132     PRUint32     send_offset; // amount of send_queue.First() already written.
    133     ipcMessage  *in_msg;
    134133    bool         fShutdown;
     134    /** The list of messages waiting for sending out. */
     135    RTLISTANCHOR LstMsgsOut;
     136    /** Number of bytes in the message of the first message on the list which was already sent. */
     137    size_t       offSendFirst;
     138    /** The message currently being received. */
     139    IPCMSG       MsgIn;
    135140};
    136141
     
    146151    RTSocketClose(s->hSockConn);
    147152
    148     if (s->in_msg)
    149         delete s->in_msg;
    150 
    151     s->send_queue.DeleteAll();
     153    IPCMsgFree(&s->MsgIn, false /*fFreeStruct*/);
     154
     155    PIPCMSG pIt, pItNext;
     156    RTListForEachSafe(&s->LstMsgsOut, pIt, pItNext, IPCMSG, NdMsg)
     157    {
     158        RTListNodeRemove(&pIt->NdMsg);
     159        IPCMsgFree(pIt, true /*fFreeStruct*/);
     160    }
     161
    152162    RTMemFree(s);
    153163}
     
    159169      return NULL;
    160170
    161     s->send_offset = 0;
    162     s->in_msg = NULL;
    163     s->fShutdown = false;
    164 
    165     int vrc = RTCritSectInit(&s->CritSect);
     171    RTListInit(&s->LstMsgsOut);
     172    s->offSendFirst = 0;
     173    s->fShutdown    = false;
     174
     175    int vrc = IPCMsgInit(&s->MsgIn, 0 /*cbBuf*/);
    166176    if (RT_SUCCESS(vrc))
    167177    {
    168         vrc = RTPollSetCreate(&s->hPollSet);
     178        vrc = RTCritSectInit(&s->CritSect);
    169179        if (RT_SUCCESS(vrc))
    170180        {
    171             RTPIPE hPipeR;
    172 
    173             vrc = RTPipeCreate(&s->hWakeupPipeR, &s->hWakeupPipeW, 0 /*fFlags*/);
     181            vrc = RTPollSetCreate(&s->hPollSet);
    174182            if (RT_SUCCESS(vrc))
    175183            {
    176                 vrc = RTPollSetAddSocket(s->hPollSet, hSockConn, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR, SOCK);
     184                vrc = RTPipeCreate(&s->hWakeupPipeR, &s->hWakeupPipeW, 0 /*fFlags*/);
    177185                if (RT_SUCCESS(vrc))
    178186                {
    179                     vrc = RTPollSetAddPipe(s->hPollSet, s->hWakeupPipeR, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR, POLL);
     187                    vrc = RTPollSetAddSocket(s->hPollSet, hSockConn, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR, SOCK);
    180188                    if (RT_SUCCESS(vrc))
    181189                    {
    182                         vrc = RTSocketSetInheritance(hSockConn, false /*fInheritable*/);
     190                        vrc = RTPollSetAddPipe(s->hPollSet, s->hWakeupPipeR, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR, POLL);
    183191                        if (RT_SUCCESS(vrc))
    184192                        {
    185                             s->hSockConn = hSockConn;
    186                             return s;
     193                            vrc = RTSocketSetInheritance(hSockConn, false /*fInheritable*/);
     194                            if (RT_SUCCESS(vrc))
     195                            {
     196                                s->hSockConn = hSockConn;
     197                                return s;
     198                            }
     199
     200                            LogFlowFunc(("coudn't make IPC socket non-inheritable [err=%Rrc]\n", vrc));
     201                            vrc = RTPollSetRemove(s->hPollSet, POLL); AssertRC(vrc);
    187202                        }
    188203
    189                         LogFlowFunc(("coudn't make IPC socket non-inheritable [err=%Rrc]\n", vrc));
    190                         vrc = RTPollSetRemove(s->hPollSet, POLL); AssertRC(vrc);
     204                        vrc = RTPollSetRemove(s->hPollSet, SOCK); AssertRC(vrc);
    191205                    }
    192206
    193                     vrc = RTPollSetRemove(s->hPollSet, SOCK); AssertRC(vrc);
     207                    vrc = RTPipeClose(s->hWakeupPipeR); AssertRC(vrc);
     208                    vrc = RTPipeClose(s->hWakeupPipeW); AssertRC(vrc);
    194209                }
    195210
    196                 vrc = RTPipeClose(s->hWakeupPipeR); AssertRC(vrc);
    197                 vrc = RTPipeClose(s->hWakeupPipeW); AssertRC(vrc);
    198             }
    199 
    200             vrc = RTPollSetDestroy(s->hPollSet); AssertRC(vrc);
    201         }
    202 
    203         RTCritSectDelete(&s->CritSect);
     211                vrc = RTPollSetDestroy(s->hPollSet); AssertRC(vrc);
     212            }
     213
     214            RTCritSectDelete(&s->CritSect);
     215        }
     216
     217        IPCMsgFree(&s->MsgIn, false /*fFreeStruct*/);
    204218    }
    205219
     
    236250        while (cbRead)
    237251        {
    238             PRUint32 bytesRead;
    239             PRBool fComplete = PR_FALSE;
    240 
    241             /* No message frame available? Allocate a new one. */
    242             if (!s->in_msg)
    243             {
    244                 s->in_msg = new ipcMessage;
    245                 if (RT_UNLIKELY(!s->in_msg))
    246                 {
    247                     rv = NS_ERROR_OUT_OF_MEMORY;
    248                     break;
    249                 }
    250             }
    251 
    252             if (s->in_msg->ReadFrom(pdata, cbRead, &bytesRead, &fComplete) != PR_SUCCESS)
     252            size_t cbProcessed = 0;
     253            bool fComplete = false;
     254
     255            if (IPCMsgReadFrom(&s->MsgIn, pdata, cbRead, &cbProcessed, &fComplete) != VINF_SUCCESS)
    253256            {
    254257                LogFlowFunc(("error reading IPC message\n"));
     
    257260            }
    258261
    259             Assert(cbRead >= bytesRead);
    260             cbRead -= bytesRead;
    261             pdata  += bytesRead;
     262            Assert(cbRead >= cbProcessed);
     263            cbRead -= cbProcessed;
     264            pdata  += cbProcessed;
    262265
    263266            if (fComplete)
    264267            {
    265                 // protect against weird re-entrancy cases...
    266                 ipcMessage *m = s->in_msg;
    267                 s->in_msg = NULL;
    268 
    269                 IPC_OnMessageAvailable(m);
     268                IPC_OnMessageAvailable(&s->MsgIn);
     269                IPCMsgReset(&s->MsgIn);
    270270            }
    271271        }
     
    281281    RTCritSectEnter(&s->CritSect);
    282282
    283     // write one message and then return.
    284     if (s->send_queue.First())
     283    /* Write as much as we can. */
     284    while (!RTListIsEmpty(&s->LstMsgsOut))
    285285    {
    286286        size_t cbWritten = 0;
     287        PIPCMSG pMsg = RTListGetFirst(&s->LstMsgsOut, IPCMSG, NdMsg);
    287288        int vrc = RTSocketWriteNB(s->hSockConn,
    288                                   s->send_queue.First()->MsgBuf() + s->send_offset,
    289                                   s->send_queue.First()->MsgLen() - s->send_offset,
     289                                  (const uint8_t *)IPCMsgGetBuf(pMsg) + s->offSendFirst,
     290                                  IPCMsgGetSize(pMsg) - s->offSendFirst,
    290291                                  &cbWritten);
    291292        if (vrc == VINF_SUCCESS && cbWritten)
    292293        {
    293             s->send_offset += cbWritten;
    294             if (s->send_offset == s->send_queue.First()->MsgLen())
    295             {
    296                 s->send_queue.DeleteFirst();
    297                 s->send_offset = 0;
    298 
    299                 /* if the send queue is empty, then we need to stop trying to write. */
    300                 if (s->send_queue.IsEmpty())
    301                 {
    302                     vrc = RTPollSetEventsChange(s->hPollSet, SOCK, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR);
    303                     AssertRC(vrc);
    304                 }
    305             }
    306         }
    307         else if (vrc != VINF_TRY_AGAIN)
     294            s->offSendFirst += cbWritten;
     295            if (s->offSendFirst == IPCMsgGetSize(pMsg))
     296            {
     297                RTListNodeRemove(&pMsg->NdMsg);
     298                IPC_MsgFree(pMsg);
     299                s->offSendFirst = 0;
     300            }
     301        }
     302        else if (vrc == VINF_TRY_AGAIN)
     303            break;
     304        else
    308305        {
    309306            Assert(RT_FAILURE(vrc));
     
    311308            rv = NS_ERROR_UNEXPECTED;
    312309        }
     310    }
     311
     312    /* if the send queue is empty, then we need to stop trying to write. */
     313    if (RTListIsEmpty(&s->LstMsgsOut))
     314    {
     315        int vrc = RTPollSetEventsChange(s->hPollSet, SOCK, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR);
     316        AssertRC(vrc);
    313317    }
    314318
     
    375379                RTCritSectEnter(&s->CritSect);
    376380
    377                 if (!s->send_queue.IsEmpty())
     381                if (!RTListIsEmpty(&s->LstMsgsOut))
    378382                {
    379383                    vrc = RTPollSetEventsChange(s->hPollSet, SOCK, RTPOLL_EVT_READ | RTPOLL_EVT_WRITE | RTPOLL_EVT_ERROR);
     
    387391                // request until after all queued up messages have been sent and until
    388392                // after all queued up callbacks have been run.
    389                 if (s->fShutdown && s->send_queue.IsEmpty() && s->callback_queue.IsEmpty())
     393                if (s->fShutdown && RTListIsEmpty(&s->LstMsgsOut) && s->callback_queue.IsEmpty())
    390394                    rv = NS_ERROR_ABORT;
    391395
     
    559563}
    560564
    561 nsresult IPC_SendMsg(ipcMessage *msg)
     565nsresult IPC_SendMsg(PIPCMSG pMsg)
    562566{
    563567    if (!gConnState || !gConnThread)
     
    565569
    566570    RTCritSectEnter(&gConnState->CritSect);
    567     gConnState->send_queue.Append(msg);
     571    RTListAppend(&gConnState->LstMsgsOut, &pMsg->NdMsg);
    568572    size_t cbWrittenIgn = 0;
    569573    int vrc = RTPipeWrite(gConnState->hWakeupPipeW, &magicChar, sizeof(magicChar), &cbWrittenIgn);
  • trunk/src/libs/xpcom18a4/ipc/ipcd/client/src/ipcService.cpp

    r102470 r103472  
    7979}
    8080
     81#if 0 /*unused*/
    8182NS_IMETHODIMP
    8283ipcService::ClientExists(PRUint32 aClientID, PRBool *aResult)
     
    8485    return IPC_ClientExists(aClientID, aResult);
    8586}
     87#endif
    8688
    8789NS_IMETHODIMP
  • trunk/src/libs/xpcom18a4/ipc/ipcd/client/src/ipcdclient.cpp

    r103331 r103472  
    3939#include "ipcConnection.h"
    4040#include "ipcConfig.h"
    41 #include "ipcMessageQ.h"
    42 #include "ipcMessageUtils.h"
    4341#include "ipcm.h"
    4442
     
    9189
    9290  // incoming messages are added to this list
    93   ipcMessageQ pendingQ;
     91  RTLISTANCHOR            LstPendingMsgs;
    9492
    9593  // non-zero if the observer has been disabled (this means that new messages
     
    104102    , observerDisabled(0)
    105103    , refcnt(0)
    106     {}
     104    {
     105        RTListInit(&LstPendingMsgs);
     106    }
    107107
    108108  ~ipcTargetData()
     
    110110    if (monitor)
    111111      nsAutoMonitor::DestroyMonitor(monitor);
     112
     113    /* Free all the pending messages. */
     114    PIPCMSG pIt, pItNext;
     115    RTListForEachSafe(&LstPendingMsgs, pIt, pItNext, IPCMSG, NdMsg)
     116    {
     117        RTListNodeRemove(&pIt->NdMsg);
     118        IPCMsgFree(pIt, true /*fFreeStruct*/);
     119    }
    112120  }
    113121
     
    153161  {
    154162    RTCritSectRwDelete(&critSect);
     163    RTCritSectDelete(&CritSectCache);
     164
     165    /* Free all the cached messages. */
     166    PIPCMSG pIt, pItNext;
     167    RTListForEachSafe(&LstMsgCache, pIt, pItNext, IPCMSG, NdMsg)
     168    {
     169        RTListNodeRemove(&pIt->NdMsg);
     170        IPCMsgFree(pIt, true /*fFreeStruct*/);
     171    }
    155172  }
    156173
     
    165182  nsCOMArray<ipcIClientObserver> clientObservers;
    166183
     184  RTCRITSECT     CritSectCache;
     185  RTLISTANCHOR  LstMsgCache;
     186  uint32_t      cMsgsInCache;
     187
    167188private:
    168189
     
    174195    /* Not employing the lock validator here to keep performance up in debug builds. */
    175196    RTCritSectRwInitEx(&critSect, RTCRITSECT_FLAGS_NO_LOCK_VAL, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_NONE, NULL);
     197
     198    RTCritSectInit(&CritSectCache);
     199    RTListInit(&LstMsgCache);
     200    cMsgsInCache = 0;
    176201  }
    177202};
     
    196221
    197222static ipcClientState *gClientState;
     223
     224DECLHIDDEN(void) IPC_MsgFree(PIPCMSG pMsg)
     225{
     226    if (pMsg->fStack)
     227        return;
     228
     229    int vrc = RTCritSectTryEnter(&gClientState->CritSectCache);
     230    if (RT_SUCCESS(vrc))
     231    {
     232        if (gClientState->cMsgsInCache < 10)
     233        {
     234            RTListAppend(&gClientState->LstMsgCache, &pMsg->NdMsg);
     235            gClientState->cMsgsInCache++;
     236            RTCritSectLeave(&gClientState->CritSectCache);
     237            return;
     238        }
     239
     240        RTCritSectLeave(&gClientState->CritSectCache);
     241    }
     242
     243    IPCMsgFree(pMsg, true /*fFreeStruct*/);
     244}
     245
     246DECLINLINE(PIPCMSG) ipcdMsgGetFromCache(void)
     247{
     248    PIPCMSG pMsg = NULL;
     249
     250    if (gClientState->cMsgsInCache)
     251    {
     252        int vrc = RTCritSectTryEnter(&gClientState->CritSectCache);
     253        if (RT_SUCCESS(vrc))
     254        {
     255            if (gClientState->cMsgsInCache)
     256            {
     257                pMsg = RTListRemoveFirst(&gClientState->LstMsgCache, IPCMSG, NdMsg);
     258                gClientState->cMsgsInCache--;
     259            }
     260
     261            RTCritSectLeave(&gClientState->CritSectCache);
     262        }
     263    }
     264
     265    return pMsg;
     266}
     267
     268static PIPCMSG IPC_MsgClone(PCIPCMSG pMsg)
     269{
     270    PIPCMSG pClone = ipcdMsgGetFromCache();
     271    if (pClone)
     272    {
     273        int vrc = IPCMsgCloneWithMsg(pMsg, pClone);
     274        if (RT_SUCCESS(vrc))
     275            return pClone;
     276
     277        /* Don't bother putting the clone back into the cache. */
     278        IPCMsgFree(pClone, true /*fFreeStruct*/);
     279    }
     280
     281    /* Allocate new */
     282    return IPCMsgClone(pMsg);
     283}
     284
     285static PIPCMSG IPC_MsgNewSg(const nsID &target, size_t cbTotal, PCRTSGSEG paSegs, uint32_t cSegs)
     286{
     287    PIPCMSG pMsg = ipcdMsgGetFromCache();
     288    if (pMsg)
     289    {
     290        int vrc = IPCMsgInitSg(pMsg, target, cbTotal, paSegs, cSegs);
     291        if (RT_SUCCESS(vrc))
     292            return pMsg;
     293    }
     294
     295    return IPCMsgNewSg(target, cbTotal, paSegs, cSegs);
     296}
     297
    198298
    199299static PRBool
     
    247347ProcessPendingQ(const nsID &aTarget)
    248348{
    249   ipcMessageQ tempQ;
    250 
    251   nsRefPtr<ipcTargetData> td;
    252   if (GetTarget(aTarget, getter_AddRefs(td)))
    253   {
    254     nsAutoMonitor mon(td->monitor);
    255 
    256     // if the observer for this target has been temporarily disabled, then
    257     // we must not processing any pending messages at this time.
    258 
    259     if (!td->observerDisabled)
    260       td->pendingQ.MoveTo(tempQ);
    261   }
    262 
    263   // process pending queue outside monitor
    264   while (!tempQ.IsEmpty())
    265   {
    266     ipcMessage *msg = tempQ.First();
    267 
    268     // it is possible that messages for other targets are in the queue
    269     // (currently, this can be only a IPCM_MSG_PSH_CLIENT_STATE message
    270     // initially addressed to IPCM_TARGET, see IPC_OnMessageAvailable())
    271     // --ignore them.
    272     if (td->observer && msg->Target().Equals(aTarget))
    273       td->observer->OnMessageAvailable(msg->mMetaData,
    274                                        msg->Target(),
    275                                        (const PRUint8 *) msg->Data(),
    276                                        msg->DataLen());
    277     else
    278     {
    279       // the IPCM target does not have an observer, and therefore any IPCM
    280       // messages that make it here will simply be dropped.
    281       NS_ASSERTION(aTarget.Equals(IPCM_TARGET) || msg->Target().Equals(IPCM_TARGET),
    282                    "unexpected target");
    283       Log(("dropping IPCM message: type=%x\n", IPCM_GetType(msg)));
    284     }
    285     tempQ.DeleteFirst();
    286   }
     349    RTLISTANCHOR LstPendingMsgs;
     350    RTListInit(&LstPendingMsgs);
     351
     352    nsRefPtr<ipcTargetData> td;
     353    if (GetTarget(aTarget, getter_AddRefs(td)))
     354    {
     355        nsAutoMonitor mon(td->monitor);
     356
     357        // if the observer for this target has been temporarily disabled, then
     358        // we must not processing any pending messages at this time.
     359
     360        if (!td->observerDisabled)
     361            RTListMove(&LstPendingMsgs, &td->LstPendingMsgs);
     362    }
     363
     364    // process pending queue outside monitor
     365    while (!RTListIsEmpty(&LstPendingMsgs))
     366    {
     367        PIPCMSG pMsg = RTListGetFirst(&LstPendingMsgs, IPCMSG, NdMsg);
     368        RTListNodeRemove(&pMsg->NdMsg);
     369
     370        // it is possible that messages for other targets are in the queue
     371        // (currently, this can be only a IPCM_MSG_PSH_CLIENT_STATE message
     372        // initially addressed to IPCM_TARGET, see IPC_OnMessageAvailable())
     373        // --ignore them.
     374        if (td->observer && IPCMsgGetTarget(pMsg)->Equals(aTarget))
     375            td->observer->OnMessageAvailable(pMsg->upUser,
     376                                             *IPCMsgGetTarget(pMsg),
     377                                             (const PRUint8 *)IPCMsgGetPayload(pMsg),
     378                                             IPCMsgGetPayloadSize(pMsg));
     379        else
     380        {
     381          // the IPCM target does not have an observer, and therefore any IPCM
     382          // messages that make it here will simply be dropped.
     383          NS_ASSERTION(   aTarget.Equals(IPCM_TARGET)
     384                       || IPCMsgGetTarget(pMsg)->Equals(IPCM_TARGET),
     385                       "unexpected target");
     386          Log(("dropping IPCM message: type=%x\n", IPCM_GetType(pMsg)));
     387        }
     388        IPC_MsgFree(pMsg);
     389    }
    287390}
    288391
     
    292395// message target.  the selector is called while inside the target's monitor.
    293396
    294 typedef nsresult (* ipcMessageSelector)(
    295   void *arg,
    296   ipcTargetData *td,
    297   const ipcMessage *msg
    298 );
     397typedef nsresult (* ipcMessageSelector)(void *arg, ipcTargetData *td, PCIPCMSG pMsg);
    299398
    300399// selects any
    301 static nsresult
    302 DefaultSelector(void *arg, ipcTargetData *td, const ipcMessage *msg)
     400static nsresult DefaultSelector(void *arg, ipcTargetData *td, PCIPCMSG pMsg)
    303401{
    304402  return NS_OK;
     
    308406WaitTarget(const nsID           &aTarget,
    309407           RTMSINTERVAL         aTimeout,
    310            ipcMessage          **aMsg,
     408           PIPCMSG              *ppMsg,
    311409           ipcMessageSelector    aSelector = nsnull,
    312410           void                 *aArg = nsnull)
    313411{
    314   *aMsg = nsnull;
     412  *ppMsg = NULL;
    315413
    316414  if (!aSelector)
     
    338436  }
    339437
    340   ipcMessage *lastChecked = nsnull, *beforeLastChecked = nsnull;
    341438  nsresult rv = NS_ERROR_ABORT;
    342439
     
    350447  while (gClientState->connected && (!gClientState->shutdown || isIPCMTarget))
    351448  {
    352     NS_ASSERTION(!lastChecked, "oops");
    353 
    354449    //
    355450    // NOTE:
     
    365460    //
    366461
    367     lastChecked = td->pendingQ.First();
    368     beforeLastChecked = nsnull;
    369 
     462    PIPCMSG pIt, pItNext;
    370463    // loop over pending queue until we find a message that our selector likes.
    371     while (lastChecked)
     464    RTListForEachSafe(&td->LstPendingMsgs, pIt, pItNext, IPCMSG, NdMsg)
    372465    {
    373466      //
     
    378471      // to guarantee that every message is processed only once.
    379472      //
    380 
    381       if (!lastChecked->TestFlag(IPC_MSG_FLAG_IN_PROCESS))
     473      if (!IPCMsgIsFlagSet(pIt, IPC_MSG_HDR_FLAG_IN_PROCESS))
    382474      {
    383         lastChecked->SetFlag(IPC_MSG_FLAG_IN_PROCESS);
    384         nsresult acceptedRV = (aSelector)(aArg, td, lastChecked);
    385         lastChecked->ClearFlag(IPC_MSG_FLAG_IN_PROCESS);
     475        IPCMsgSetFlag(pIt, IPC_MSG_HDR_FLAG_IN_PROCESS);
     476        nsresult acceptedRV = (aSelector)(aArg, td, pIt);
     477        IPCMsgClearFlag(pIt, IPC_MSG_HDR_FLAG_IN_PROCESS);
    386478
    387479        if (acceptedRV != IPC_WAIT_NEXT_MESSAGE)
     
    390482          {
    391483            // remove from pending queue
    392             if (beforeLastChecked)
    393               td->pendingQ.RemoveAfter(beforeLastChecked);
    394             else
    395               td->pendingQ.RemoveFirst();
    396 
    397             lastChecked->mNext = nsnull;
    398             *aMsg = lastChecked;
     484            RTListNodeRemove(&pIt->NdMsg);
     485            *ppMsg = pIt;
    399486            break;
    400487          }
    401488          else /* acceptedRV == IPC_DISCARD_MESSAGE */
    402489          {
    403             ipcMessage *nextToCheck = lastChecked->mNext;
    404 
    405             // discard from pending queue
    406             if (beforeLastChecked)
    407               td->pendingQ.DeleteAfter(beforeLastChecked);
    408             else
    409               td->pendingQ.DeleteFirst();
    410 
    411             lastChecked = nextToCheck;
    412 
     490            RTListNodeRemove(&pIt->NdMsg);
     491            IPC_MsgFree(pIt);
    413492            continue;
    414493          }
    415494        }
    416495      }
    417 
    418       beforeLastChecked = lastChecked;
    419       lastChecked = lastChecked->mNext;
    420     }
    421 
    422     if (*aMsg)
     496    }
     497
     498    if (*ppMsg)
    423499    {
    424500      rv = NS_OK;
     
    434510      if (aliveRV != IPC_WAIT_NEXT_MESSAGE)
    435511      {
    436         *aMsg = NULL;
     512        *ppMsg = NULL;
    437513        break;
    438514      }
     
    452528
    453529    Log(("woke up from sleep [pendingQempty=%d connected=%d shutdown=%d isIPCMTarget=%d]\n",
    454           td->pendingQ.IsEmpty(), gClientState->connected,
     530          RTListIsEmpty(&td->LstPendingMsgs), gClientState->connected,
    455531          gClientState->shutdown, isIPCMTarget));
    456532  }
     
    592668    nsAutoMonitor mon(td->monitor);
    593669    if (td->observerDisabled > 0 && --td->observerDisabled == 0)
    594       if (!td->pendingQ.IsEmpty())
     670      if (!RTListIsEmpty(&td->LstPendingMsgs))
    595671        CallProcessPendingQ(aTarget, td);
    596672  }
     
    600676
    601677// converts IPCM_ERROR_* status codes to NS_ERROR_* status codes
    602 static nsresult nsresult_from_ipcm_result(PRInt32 status)
     678static nsresult nsresult_from_ipcm_result(int32_t status)
    603679{
    604680  nsresult rv = NS_ERROR_FAILURE;
     
    622698// selects the next IPCM message with matching request index
    623699static nsresult
    624 WaitIPCMResponseSelector(void *arg, ipcTargetData *td, const ipcMessage *msg)
     700WaitIPCMResponseSelector(void *arg, ipcTargetData *td, PCIPCMSG pMsg)
    625701{
    626702#ifdef VBOX
    627   if (!msg)
     703  if (!pMsg)
    628704    return IPC_WAIT_NEXT_MESSAGE;
    629705#endif /* VBOX */
    630706  PRUint32 requestIndex = *(PRUint32 *) arg;
    631   return IPCM_GetRequestIndex(msg) == requestIndex ? NS_OK : IPC_WAIT_NEXT_MESSAGE;
     707  return IPCM_GetRequestIndex(pMsg) == requestIndex ? NS_OK : IPC_WAIT_NEXT_MESSAGE;
    632708}
    633709
     
    637713// status code is mapped to a nsresult and returned by this function.
    638714static nsresult
    639 WaitIPCMResponse(PRUint32 requestIndex, ipcMessage **responseMsg = nsnull)
    640 {
    641   ipcMessage *msg;
    642 
    643   nsresult rv = WaitTarget(IPCM_TARGET, IPC_REQUEST_TIMEOUT, &msg,
     715WaitIPCMResponse(PRUint32 requestIndex, PIPCMSG *ppMsgResponse = NULL)
     716{
     717  PIPCMSG pMsg;
     718
     719  nsresult rv = WaitTarget(IPCM_TARGET, IPC_REQUEST_TIMEOUT, &pMsg,
    644720                           WaitIPCMResponseSelector, &requestIndex);
    645721  if (NS_FAILED(rv))
    646722    return rv;
    647723
    648   if (IPCM_GetType(msg) == IPCM_MSG_ACK_RESULT)
    649   {
    650     ipcMessageCast<ipcmMessageResult> result(msg);
    651     if (result->Status() < 0)
    652       rv = nsresult_from_ipcm_result(result->Status());
     724  if (IPCM_GetType(pMsg) == IPCM_MSG_ACK_RESULT)
     725  {
     726    PCIPCMMSGRESULT pIpcmRes = (PCIPCMMSGRESULT)IPCMsgGetPayload(pMsg);
     727    if (pIpcmRes->i32Status < 0)
     728      rv = nsresult_from_ipcm_result(pIpcmRes->i32Status);
    653729    else
    654730      rv = NS_OK;
    655731  }
    656732
    657   if (responseMsg)
    658     *responseMsg = msg;
     733  if (ppMsgResponse)
     734    *ppMsgResponse = pMsg;
    659735  else
    660     delete msg;
     736    IPC_MsgFree(pMsg);
    661737
    662738  return rv;
     
    665741// make an IPCM request and wait for a response.
    666742static nsresult
    667 MakeIPCMRequest(ipcMessage *msg, ipcMessage **responseMsg = nsnull)
    668 {
    669   if (!msg)
    670     return NS_ERROR_OUT_OF_MEMORY;
    671 
    672   PRUint32 requestIndex = IPCM_GetRequestIndex(msg);
    673 
    674   // suppress 'ProcessPendingQ' for IPCM messages until we receive the
    675   // response to this IPCM request.  if we did not do this then there
    676   // would be a race condition leading to the possible removal of our
    677   // response from the pendingQ between sending the request and waiting
    678   // for the response.
    679   DisableMessageObserver(IPCM_TARGET);
    680 
    681   nsresult rv = IPC_SendMsg(msg);
    682   if (NS_SUCCEEDED(rv))
    683     rv = WaitIPCMResponse(requestIndex, responseMsg);
    684 
    685   EnableMessageObserver(IPCM_TARGET);
    686   return rv;
    687 }
    688 
    689 /* ------------------------------------------------------------------------- */
    690 
    691 static void
    692 RemoveTarget(const nsID &aTarget, PRBool aNotifyDaemon)
    693 {
    694   DelTarget(aTarget);
    695 
    696   if (aNotifyDaemon)
    697   {
    698     nsresult rv = MakeIPCMRequest(new ipcmMessageClientDelTarget(aTarget));
    699     if (NS_FAILED(rv))
    700       Log(("failed to delete target: rv=%x\n", rv));
    701   }
     743MakeIPCMRequest(PIPCMSG pMsg, PIPCMSG *ppMsgResponse = NULL)
     744{
     745    AssertPtrReturn(pMsg, NS_ERROR_OUT_OF_MEMORY);
     746
     747    uint32_t requestIndex = IPCM_GetRequestIndex(pMsg);
     748
     749    // suppress 'ProcessPendingQ' for IPCM messages until we receive the
     750    // response to this IPCM request.  if we did not do this then there
     751    // would be a race condition leading to the possible removal of our
     752    // response from the pendingQ between sending the request and waiting
     753    // for the response.
     754    DisableMessageObserver(IPCM_TARGET);
     755
     756    nsresult rv = IPC_SendMsg(pMsg);
     757    if (NS_SUCCEEDED(rv))
     758        rv = WaitIPCMResponse(requestIndex, ppMsgResponse);
     759
     760    EnableMessageObserver(IPCM_TARGET);
     761    return rv;
     762}
     763
     764/* ------------------------------------------------------------------------- */
     765
     766static void RemoveTarget(const nsID &aTarget, PRBool aNotifyDaemon)
     767{
     768    DelTarget(aTarget);
     769
     770    if (aNotifyDaemon)
     771    {
     772        IPCMMSGSTACK IpcmMsg;
     773        IPCMSG IpcMsg;
     774
     775        IPCMMsgDelTargetInit(&IpcmMsg.Ipcm.AddDelTarget, aTarget);
     776        IPCMsgInitStack(&IpcMsg, IPCM_TARGET, &IpcmMsg, sizeof(IpcmMsg.Ipcm.AddDelTarget));
     777        nsresult rv = MakeIPCMRequest(&IpcMsg);
     778        if (NS_FAILED(rv))
     779            Log(("failed to delete target: rv=%x\n", rv));
     780    }
    702781}
    703782
     
    709788             ipcTargetData       **aResult)
    710789{
    711   nsresult rv;
    712 
    713   nsRefPtr<ipcTargetData> td( ipcTargetData::Create() );
    714   if (!td)
    715     return NS_ERROR_OUT_OF_MEMORY;
    716   td->SetObserver(aObserver, aOnCurrentThread);
    717 
    718   if (!PutTarget(aTarget, td))
    719     return NS_ERROR_OUT_OF_MEMORY;
    720 
    721   if (aNotifyDaemon)
    722   {
    723     rv = MakeIPCMRequest(new ipcmMessageClientAddTarget(aTarget));
    724     if (NS_FAILED(rv))
    725     {
    726       Log(("failed to add target: rv=%x\n", rv));
    727       RemoveTarget(aTarget, PR_FALSE);
    728       return rv;
    729     }
    730   }
    731 
    732   if (aResult)
    733     NS_ADDREF(*aResult = td);
    734   return NS_OK;
     790    nsresult rv;
     791
     792    nsRefPtr<ipcTargetData> td( ipcTargetData::Create() );
     793    if (!td)
     794        return NS_ERROR_OUT_OF_MEMORY;
     795    td->SetObserver(aObserver, aOnCurrentThread);
     796
     797    if (!PutTarget(aTarget, td))
     798        return NS_ERROR_OUT_OF_MEMORY;
     799
     800    if (aNotifyDaemon)
     801    {
     802        IPCMMSGSTACK IpcmMsg;
     803        IPCMSG IpcMsg;
     804
     805        IPCMMsgAddTargetInit(&IpcmMsg.Ipcm.AddDelTarget, aTarget);
     806        IPCMsgInitStack(&IpcMsg, IPCM_TARGET, &IpcmMsg, sizeof(IpcmMsg.Ipcm.AddDelTarget));
     807        rv = MakeIPCMRequest(&IpcMsg);
     808        if (NS_FAILED(rv))
     809        {
     810          Log(("failed to add target: rv=%x\n", rv));
     811          RemoveTarget(aTarget, PR_FALSE);
     812          return rv;
     813        }
     814    }
     815
     816    if (aResult)
     817        NS_ADDREF(*aResult = td);
     818    return NS_OK;
    735819}
    736820
     
    740824TryConnect()
    741825{
    742   nsCAutoString dpath;
    743   nsresult rv = GetDaemonPath(dpath);
    744   if (NS_FAILED(rv))
     826    nsCAutoString dpath;
     827    nsresult rv = GetDaemonPath(dpath);
     828    if (NS_FAILED(rv))
     829        return rv;
     830
     831    rv = IPC_Connect(dpath.get());
     832    if (NS_FAILED(rv))
     833        return rv;
     834
     835    gClientState->connected = PR_TRUE;
     836
     837    rv = DefineTarget(IPCM_TARGET, nsnull, PR_FALSE, PR_FALSE, nsnull);
     838    if (NS_FAILED(rv))
     839        return rv;
     840
     841    PIPCMSG pMsg = NULL;
     842
     843    // send CLIENT_HELLO and wait for CLIENT_ID response...
     844    IPCMMSGSTACK IpcmMsg;
     845    IPCMSG IpcMsg;
     846
     847    IPCMMsgClientHelloInit(&IpcmMsg.Ipcm.ClientHello);
     848    IPCMsgInitStack(&IpcMsg, IPCM_TARGET, &IpcmMsg, sizeof(IpcmMsg.Ipcm.ClientHello));
     849    rv = MakeIPCMRequest(&IpcMsg, &pMsg);
     850    if (NS_FAILED(rv))
     851    {
     852#ifdef VBOX  /* MakeIPCMRequest may return a failure (e.g. NS_ERROR_CALL_FAILED) and a response msg. */
     853        if (pMsg)
     854            IPC_MsgFree(pMsg);
     855#endif
     856        return rv;
     857    }
     858
     859    if (IPCM_GetType(pMsg) == IPCM_MSG_ACK_CLIENT_ID)
     860    {
     861        PCIPCMMSGCLIENTID pIpcmClientId = (PCIPCMMSGCLIENTID)IPCMsgGetPayload(pMsg);
     862        gClientState->selfID = pIpcmClientId->u32ClientId;
     863    }
     864    else
     865    {
     866        Log(("unexpected response from CLIENT_HELLO message: type=%x!\n", IPCM_GetType(pMsg)));
     867        rv = NS_ERROR_UNEXPECTED;
     868    }
     869
     870    IPC_MsgFree(pMsg);
    745871    return rv;
    746 
    747   rv = IPC_Connect(dpath.get());
    748   if (NS_FAILED(rv))
    749     return rv;
    750 
    751   gClientState->connected = PR_TRUE;
    752 
    753   rv = DefineTarget(IPCM_TARGET, nsnull, PR_FALSE, PR_FALSE, nsnull);
    754   if (NS_FAILED(rv))
    755     return rv;
    756 
    757   ipcMessage *msg = NULL;
    758 
    759   // send CLIENT_HELLO and wait for CLIENT_ID response...
    760   rv = MakeIPCMRequest(new ipcmMessageClientHello(), &msg);
    761   if (NS_FAILED(rv))
    762   {
    763 #ifdef VBOX  /* MakeIPCMRequest may return a failure (e.g. NS_ERROR_CALL_FAILED) and a response msg. */
    764     if (msg)
    765       delete msg;
    766 #endif
    767     return rv;
    768   }
    769 
    770   if (IPCM_GetType(msg) == IPCM_MSG_ACK_CLIENT_ID)
    771     gClientState->selfID = ipcMessageCast<ipcmMessageClientID>(msg)->ClientID();
    772   else
    773   {
    774     Log(("unexpected response from CLIENT_HELLO message: type=%x!\n",
    775         IPCM_GetType(msg)));
    776     rv = NS_ERROR_UNEXPECTED;
    777   }
    778 
    779   delete msg;
    780   return rv;
    781872}
    782873
     
    9251016                PRUint32       aDataLen)
    9261017{
    927   NS_ENSURE_TRUE(gClientState, NS_ERROR_NOT_INITIALIZED);
    928 
    929   // do not permit sending IPCM messages
    930   if (aTarget.Equals(IPCM_TARGET))
    931     return NS_ERROR_INVALID_ARG;
    932 
    933   nsresult rv;
    934   if (aReceiverID == 0)
    935   {
    936     ipcMessage *msg = new ipcMessage(aTarget, (const char *) aData, aDataLen);
    937     if (!msg)
    938       return NS_ERROR_OUT_OF_MEMORY;
    939 
    940     rv = IPC_SendMsg(msg);
    941   }
    942   else
    943     rv = MakeIPCMRequest(new ipcmMessageForward(IPCM_MSG_REQ_FORWARD,
    944                                                 aReceiverID,
    945                                                 aTarget,
    946                                                 (const char *) aData,
    947                                                 aDataLen));
    948 
    949   return rv;
     1018    NS_ENSURE_TRUE(gClientState, NS_ERROR_NOT_INITIALIZED);
     1019
     1020    // do not permit sending IPCM messages
     1021    if (aTarget.Equals(IPCM_TARGET))
     1022      return NS_ERROR_INVALID_ARG;
     1023
     1024    nsresult rv;
     1025    if (aReceiverID == 0)
     1026    {
     1027        RTSGSEG Seg = { (void *)aData, aDataLen };
     1028        PIPCMSG pMsg = IPC_MsgNewSg(aTarget, aDataLen, &Seg, 1 /*cSegs*/);
     1029        if (!pMsg)
     1030            return NS_ERROR_OUT_OF_MEMORY;
     1031
     1032        rv = IPC_SendMsg(pMsg);
     1033    }
     1034    else
     1035    {
     1036        IPCMSGHDR InnerMsgHdr;
     1037        IPCMMSGFORWARD IpcmFwd;
     1038        RTSGSEG aSegs[3];
     1039
     1040        /* Construct the forwarded message. */
     1041        IpcmFwd.Hdr.u32Type         = IPCM_MSG_REQ_FORWARD;
     1042        IpcmFwd.Hdr.u32RequestIndex = IPCM_NewRequestIndex();
     1043        IpcmFwd.u32ClientId         = aReceiverID;
     1044
     1045        aSegs[0].pvSeg = &IpcmFwd;
     1046        aSegs[0].cbSeg = sizeof(IpcmFwd);
     1047        aSegs[1].pvSeg = IPCMsgHdrInit(&InnerMsgHdr, aTarget, aDataLen);
     1048        aSegs[1].cbSeg = sizeof(InnerMsgHdr);
     1049        aSegs[2].pvSeg = (void *)aData;
     1050        aSegs[2].cbSeg = aDataLen;
     1051
     1052        PIPCMSG pMsg = IPC_MsgNewSg(IPCM_TARGET, aDataLen + sizeof(IpcmFwd) + sizeof(InnerMsgHdr),
     1053                                    &aSegs[0], RT_ELEMENTS(aSegs));
     1054        rv = MakeIPCMRequest(pMsg);
     1055    }
     1056
     1057    return rv;
    9501058}
    9511059
     
    9571065};
    9581066
    959 static nsresult WaitMessageSelector(void *arg, ipcTargetData *td, const ipcMessage *msg)
     1067static nsresult WaitMessageSelector(void *arg, ipcTargetData *td, PCIPCMSG pMsg)
    9601068{
    9611069  WaitMessageSelectorData *data = (WaitMessageSelectorData *) arg;
    9621070#ifdef VBOX
    963   if (!msg)
     1071  if (!pMsg)
    9641072  {
    9651073    /* Special NULL message which asks to check whether the client is
     
    9811089  // sender we're waiting a message from has died.
    9821090
    983   if (msg->Target().Equals(IPCM_TARGET))
    984   {
    985     switch (IPCM_GetType(msg))
     1091  if (IPCMsgGetTarget(pMsg)->Equals(IPCM_TARGET))
     1092  {
     1093    switch (IPCM_GetType(pMsg))
    9861094    {
    9871095      case IPCM_MSG_PSH_CLIENT_STATE:
    9881096      {
    989         ipcMessageCast<ipcmMessageClientState> status(msg);
     1097        PCIPCMMSGCLIENTSTATE pClientState = (PCIPCMMSGCLIENTSTATE)IPCMsgGetPayload(pMsg);
    9901098        if ((data->senderID == IPC_SENDER_ANY ||
    991              status->ClientID() == data->senderID) &&
    992             status->ClientState() == IPCM_CLIENT_STATE_DOWN)
     1099             pClientState->u32ClientId == data->senderID) &&
     1100             pClientState->u32ClientStatus == IPCM_CLIENT_STATE_DOWN)
    9931101        {
    9941102          Log(("sender (%d) we're waiting a message from (%d) has died\n",
    995                status->ClientID(), data->senderID));
     1103               pClientState->u32ClientId, data->senderID));
    9961104
    9971105          if (data->senderID != IPC_SENDER_ANY)
     
    10141122            NS_ASSERTION(obs, "must at least have a default observer");
    10151123
    1016             nsresult rv = obs->OnMessageAvailable(status->ClientID(), nsID(), 0, 0);
     1124            nsresult rv = obs->OnMessageAvailable(pClientState->u32ClientId, nsID(), 0, 0);
    10171125            if (rv != IPC_WAIT_NEXT_MESSAGE)
    10181126              data->senderDead = PR_TRUE;
     
    10231131#ifdef VBOX
    10241132        else if ((data->senderID == IPC_SENDER_ANY ||
    1025                   status->ClientID() == data->senderID) &&
    1026                  status->ClientState() == IPCM_CLIENT_STATE_UP)
     1133                  pClientState->u32ClientId) &&
     1134                 pClientState->u32ClientStatus == IPCM_CLIENT_STATE_UP)
    10271135        {
    10281136          Log(("sender (%d) we're waiting a message from (%d) has come up\n",
    1029                status->ClientID(), data->senderID));
     1137               pClientState->u32ClientId, data->senderID));
    10301138          if (data->senderID == IPC_SENDER_ANY)
    10311139          {
     
    10381146            NS_ASSERTION(obs, "must at least have a default observer");
    10391147
    1040             nsresult rv = obs->OnMessageAvailable(status->ClientID(), nsID(), 0, 1);
     1148            nsresult rv = obs->OnMessageAvailable(pClientState->u32ClientId, nsID(), 0, 1);
    10411149            /* VBoxSVC/VBoxXPCOMIPCD auto-start can cause that a client up
    10421150             * message arrives while we're already waiting for a response
     
    10621170
    10631171  if (data->senderID == IPC_SENDER_ANY ||
    1064       msg->mMetaData == data->senderID)
     1172      pMsg->upUser == data->senderID)
    10651173  {
    10661174    ipcIMessageObserver *obs = data->observer;
     
    10691177    NS_ASSERTION(obs, "must at least have a default observer");
    10701178
    1071     rv = obs->OnMessageAvailable(msg->mMetaData,
    1072                                  msg->Target(),
    1073                                  (const PRUint8 *) msg->Data(),
    1074                                  msg->DataLen());
     1179    rv = obs->OnMessageAvailable(pMsg->upUser,
     1180                                 *IPCMsgGetTarget(pMsg),
     1181                                 (const PRUint8 *)IPCMsgGetPayload(pMsg),
     1182                                 IPCMsgGetPayloadSize(pMsg));
    10751183  }
    10761184
     
    10951203  WaitMessageSelectorData data = { aSenderID, aObserver, PR_FALSE };
    10961204
    1097   ipcMessage *msg;
    1098   nsresult rv = WaitTarget(aTarget, aTimeout, &msg, WaitMessageSelector, &data);
     1205  PIPCMSG pMsg;
     1206  nsresult rv = WaitTarget(aTarget, aTimeout, &pMsg, WaitMessageSelector, &data);
    10991207  if (NS_FAILED(rv))
    11001208    return rv;
     
    11061214  if (aObserver && aConsumer)
    11071215  {
    1108     aConsumer->OnMessageAvailable(msg->mMetaData,
    1109                                   msg->Target(),
    1110                                   (const PRUint8 *) msg->Data(),
    1111                                   msg->DataLen());
    1112   }
    1113 
    1114   delete msg;
     1216    aConsumer->OnMessageAvailable(pMsg->upUser,
     1217                                  *IPCMsgGetTarget(pMsg),
     1218                                  (const PRUint8 *)IPCMsgGetPayload(pMsg),
     1219                                  IPCMsgGetPayloadSize(pMsg));
     1220  }
     1221
     1222  IPC_MsgFree(pMsg);
    11151223
    11161224  // if the requested sender has died while waiting, return an error
     
    11351243IPC_AddName(const char *aName)
    11361244{
    1137   NS_ENSURE_TRUE(gClientState, NS_ERROR_NOT_INITIALIZED);
    1138 
    1139   return MakeIPCMRequest(new ipcmMessageClientAddName(aName));
     1245    NS_ENSURE_TRUE(gClientState, NS_ERROR_NOT_INITIALIZED);
     1246
     1247    size_t cbStr = strlen(aName) + 1; /* Includes terminator. */
     1248    const IPCMMSGHDR Hdr = { IPCM_MSG_REQ_CLIENT_ADD_NAME, IPCM_NewRequestIndex() };
     1249    RTSGSEG aSegs[2];
     1250
     1251    aSegs[0].pvSeg = (void *)&Hdr;
     1252    aSegs[0].cbSeg = sizeof(Hdr);
     1253
     1254    aSegs[1].pvSeg = (void *)aName;
     1255    aSegs[1].cbSeg = cbStr;
     1256
     1257    PIPCMSG pMsg = IPC_MsgNewSg(IPCM_TARGET, cbStr + sizeof(Hdr),
     1258                                &aSegs[0], RT_ELEMENTS(aSegs));
     1259    return MakeIPCMRequest(pMsg);
    11401260}
    11411261
     
    11431263IPC_RemoveName(const char *aName)
    11441264{
    1145   NS_ENSURE_TRUE(gClientState, NS_ERROR_NOT_INITIALIZED);
    1146 
    1147   return MakeIPCMRequest(new ipcmMessageClientDelName(aName));
     1265    NS_ENSURE_TRUE(gClientState, NS_ERROR_NOT_INITIALIZED);
     1266
     1267    size_t cbStr = strlen(aName) + 1; /* Includes terminator. */
     1268    const IPCMMSGHDR Hdr = { IPCM_MSG_REQ_CLIENT_DEL_NAME, IPCM_NewRequestIndex() };
     1269    RTSGSEG aSegs[2];
     1270
     1271    aSegs[0].pvSeg = (void *)&Hdr;
     1272    aSegs[0].cbSeg = sizeof(Hdr);
     1273
     1274    aSegs[1].pvSeg = (void *)aName;
     1275    aSegs[1].cbSeg = cbStr;
     1276
     1277    PIPCMSG pMsg = IPC_MsgNewSg(IPCM_TARGET, cbStr + sizeof(Hdr),
     1278                                &aSegs[0], RT_ELEMENTS(aSegs));
     1279    return MakeIPCMRequest(pMsg);
    11481280}
    11491281
     
    11791311IPC_ResolveClientName(const char *aName, PRUint32 *aClientID)
    11801312{
    1181   NS_ENSURE_TRUE(gClientState, NS_ERROR_NOT_INITIALIZED);
    1182 
    1183   ipcMessage *msg = NULL;
    1184 
    1185   nsresult rv = MakeIPCMRequest(new ipcmMessageQueryClientByName(aName), &msg);
    1186   if (NS_FAILED(rv))
    1187   {
    1188 #ifdef VBOX  /* MakeIPCMRequest may return a failure (e.g. NS_ERROR_CALL_FAILED) and a response msg. */
    1189     if (msg)
    1190       delete msg;
    1191 #endif
     1313    NS_ENSURE_TRUE(gClientState, NS_ERROR_NOT_INITIALIZED);
     1314
     1315    size_t cbStr = strlen(aName) + 1; /* Includes terminator. */
     1316    const IPCMMSGHDR Hdr = { IPCM_MSG_REQ_QUERY_CLIENT_BY_NAME, IPCM_NewRequestIndex() };
     1317    RTSGSEG aSegs[2];
     1318
     1319    aSegs[0].pvSeg = (void *)&Hdr;
     1320    aSegs[0].cbSeg = sizeof(Hdr);
     1321
     1322    aSegs[1].pvSeg = (void *)aName;
     1323    aSegs[1].cbSeg = cbStr;
     1324
     1325    PIPCMSG pMsg = IPC_MsgNewSg(IPCM_TARGET, cbStr + sizeof(Hdr),
     1326                                &aSegs[0], RT_ELEMENTS(aSegs));
     1327
     1328    PIPCMSG pMsgResp = NULL;
     1329    nsresult rv = MakeIPCMRequest(pMsg, &pMsgResp);
     1330    if (NS_FAILED(rv))
     1331    {
     1332        /* MakeIPCMRequest may return a failure (e.g. NS_ERROR_CALL_FAILED) and a response msg. */
     1333        if (pMsgResp)
     1334            IPC_MsgFree(pMsgResp);
     1335
     1336        return rv;
     1337    }
     1338
     1339    if (IPCM_GetType(pMsgResp) == IPCM_MSG_ACK_CLIENT_ID)
     1340    {
     1341        PCIPCMMSGCLIENTID pClientId = (PCIPCMMSGCLIENTID)IPCMsgGetPayload(pMsgResp);
     1342        *aClientID = pClientId->u32ClientId;
     1343    }
     1344    else
     1345    {
     1346        Log(("unexpected IPCM response: type=%x\n", IPCM_GetType(pMsg)));
     1347        rv = NS_ERROR_UNEXPECTED;
     1348    }
     1349
     1350    IPC_MsgFree(pMsgResp);
    11921351    return rv;
    1193   }
    1194 
    1195   if (IPCM_GetType(msg) == IPCM_MSG_ACK_CLIENT_ID)
    1196     *aClientID = ipcMessageCast<ipcmMessageClientID>(msg)->ClientID();
    1197   else
    1198   {
    1199     Log(("unexpected IPCM response: type=%x\n", IPCM_GetType(msg)));
    1200     rv = NS_ERROR_UNEXPECTED;
    1201   }
    1202 
    1203   delete msg;
    1204   return rv;
    1205 }
    1206 
    1207 /* ------------------------------------------------------------------------- */
    1208 
    1209 nsresult
    1210 IPC_ClientExists(PRUint32 aClientID, PRBool *aResult)
    1211 {
    1212   // this is a bit of a hack.  we forward a PING to the specified client.
    1213   // the assumption is that the forwarding will only succeed if the client
    1214   // exists, so we wait for the RESULT message corresponding to the FORWARD
    1215   // request.  if that gives a successful status, then we know that the
    1216   // client exists.
    1217 
    1218   ipcmMessagePing ping;
    1219 
    1220   return MakeIPCMRequest(new ipcmMessageForward(IPCM_MSG_REQ_FORWARD,
    1221                                                 aClientID,
    1222                                                 IPCM_TARGET,
    1223                                                 ping.Data(),
    1224                                                 ping.DataLen()));
    1225 }
     1352}
     1353
    12261354
    12271355/* ------------------------------------------------------------------------- */
     
    12461374                                         "--inherit-startup-pipe",
    12471375                                         &szPipeInheritFd[0], NULL };
    1248       char c;
    12491376
    12501377      ssize_t cch = RTStrFormatU32(&szPipeInheritFd[0], sizeof(szPipeInheritFd),
    12511378                                   (uint32_t)RTPipeToNative(hPipeWr), 10 /*uiBase*/,
    12521379                                   0 /*cchWidth*/, 0 /*cchPrecision*/, 0 /*fFlags*/);
    1253       Assert(cch > 0);
     1380      Assert(cch > 0); RT_NOREF(cch);
    12541381
    12551382      RTHANDLE hStdNil;
     
    13151442
    13161443static void
    1317 PlaceOnPendingQ(const nsID &target, ipcTargetData *td, ipcMessage *msg)
     1444PlaceOnPendingQ(const nsID &target, ipcTargetData *td, PIPCMSG pMsg)
    13181445{
    13191446  nsAutoMonitor mon(td->monitor);
     
    13211448  // we only want to dispatch a 'ProcessPendingQ' event if we have not
    13221449  // already done so.
    1323   PRBool dispatchEvent = td->pendingQ.IsEmpty();
     1450  PRBool dispatchEvent = RTListIsEmpty(&td->LstPendingMsgs);
    13241451
    13251452  // put this message on our pending queue
    1326   td->pendingQ.Append(msg);
     1453  RTListAppend(&td->LstPendingMsgs, &pMsg->NdMsg);
    13271454
    13281455#ifdef LOG_ENABLED
     
    13501477  {
    13511478    // place a message clone to a target's event queue
    1352     ipcMessage *msg = (ipcMessage *) userArg;
    1353     PlaceOnPendingQ(aKey, aData, msg->Clone());
     1479    PCIPCMSG pMsg = (PCIPCMSG)userArg;
     1480    PlaceOnPendingQ(aKey, aData, IPC_MsgClone(pMsg));
    13541481  }
    13551482
     
    13601487
    13611488// called on a background thread
    1362 void
    1363 IPC_OnMessageAvailable(ipcMessage *msg)
    1364 {
     1489DECLHIDDEN(void) IPC_OnMessageAvailable(PCIPCMSG pMsg)
     1490{
     1491  const nsID target = *IPCMsgGetTarget(pMsg);
     1492
    13651493#ifdef LOG_ENABLED
    13661494  {
    1367     char *targetStr = msg->Target().ToString();
     1495    char *targetStr = target.ToString();
    13681496    Log(("got message for target: %s\n", targetStr));
    13691497    nsMemory::Free(targetStr);
     
    13731501#endif
    13741502
    1375   if (msg->Target().Equals(IPCM_TARGET))
    1376   {
    1377     switch (IPCM_GetType(msg))
    1378     {
    1379       // if this is a forwarded message, then post the inner message instead.
     1503  if (target.Equals(IPCM_TARGET))
     1504  {
     1505    switch (IPCM_GetType(pMsg))
     1506    {
    13801507      case IPCM_MSG_PSH_FORWARD:
    13811508      {
    1382         ipcMessageCast<ipcmMessageForward> fwd(msg);
    1383         ipcMessage *innerMsg = new ipcMessage(fwd->InnerTarget(),
    1384                                               fwd->InnerData(),
    1385                                               fwd->InnerDataLen());
    1386         // store the sender's client id in the meta-data field of the message.
    1387         innerMsg->mMetaData = fwd->ClientID();
    1388 
    1389         delete msg;
    1390 
    1391         // recurse so we can handle forwarded IPCM messages
    1392         IPC_OnMessageAvailable(innerMsg);
     1509        PCIPCMMSGFORWARD pFwd = (PCIPCMMSGFORWARD)IPCMsgGetPayload(pMsg);
     1510
     1511        /** @todo De-uglify this. */
     1512        /* Forward the inner message. */
     1513        IPCMSG InnerMsg; RT_ZERO(InnerMsg);
     1514        InnerMsg.pMsgHdr = (PIPCMSGHDR)(pFwd + 1);
     1515        InnerMsg.cbBuf   = InnerMsg.pMsgHdr->cbMsg;
     1516        InnerMsg.pbBuf   = (uint8_t *)InnerMsg.pMsgHdr;
     1517        InnerMsg.upUser  = pFwd->u32ClientId;
     1518
     1519        /* Recurse to forward the inner message (it will get cloned). */
     1520        IPC_OnMessageAvailable(&InnerMsg);
    13931521        return;
    13941522      }
    13951523      case IPCM_MSG_PSH_CLIENT_STATE:
    13961524      {
    1397         ipcMessageCast<ipcmMessageClientState> status(msg);
    1398         PostEventToMainThread(new ipcEvent_ClientState(status->ClientID(),
    1399                                                        status->ClientState()));
     1525        PCIPCMMSGCLIENTSTATE pClientState = (PCIPCMMSGCLIENTSTATE)IPCMsgGetPayload(pMsg);
     1526        PostEventToMainThread(new ipcEvent_ClientState(pClientState->u32ClientId,
     1527                                                       pClientState->u32ClientStatus));
    14001528
    14011529        // go through the target map, and place this message to every target's
     
    14041532        // the peer client death, when appropriate.
    14051533        RTCritSectRwEnterShared(&gClientState->critSect);
    1406         gClientState->targetMap.EnumerateRead(EnumerateTargetMapAndPlaceMsg, msg);
     1534        gClientState->targetMap.EnumerateRead(EnumerateTargetMapAndPlaceMsg, (void *)pMsg);
    14071535        RTCritSectRwLeaveShared(&gClientState->critSect);
    1408 
    1409         delete msg;
    14101536        return;
    14111537      }
     
    14141540
    14151541  nsRefPtr<ipcTargetData> td;
    1416   if (GetTarget(msg->Target(), getter_AddRefs(td)))
    1417   {
    1418     // make copy of target since |msg| may end up pointing to free'd memory
    1419     // once we notify the monitor inside PlaceOnPendingQ().
    1420     const nsID target = msg->Target();
    1421 
    1422     PlaceOnPendingQ(target, td, msg);
     1542  if (GetTarget(target, getter_AddRefs(td)))
     1543  {
     1544    PIPCMSG pClone = IPC_MsgClone(pMsg);
     1545    PlaceOnPendingQ(target, td, pClone);
    14231546  }
    14241547  else
    1425   {
    14261548    NS_WARNING("message target is undefined");
    1427 #ifdef VBOX
    1428     delete msg;
    1429 #endif
    1430   }
    1431 }
     1549}
  • trunk/src/libs/xpcom18a4/ipc/ipcd/daemon/src/ipcCommandModule.cpp

    r103378 r103472  
    5151
    5252
    53 DECLINLINE(uint32_t) IPCM_GetType(PCIPCMSG pMsg)
    54 {
    55     return ((const ipcmMessageHeader *)IPCMsgGetPayload(pMsg))->mType;
    56 }
    57 
    58 
    59 DECLINLINE(uint32_t) IPCM_GetRequestIndex(PCIPCMSG pMsg)
    60 {
    61     return ((const ipcmMessageHeader *)IPCMsgGetPayload(pMsg))->mRequestIndex;
    62 }
    63 
    6453//
    6554// message handlers
     
    7059    Log(("got PING\n"));
    7160
    72     const uint32_t aResp[3] = { IPCM_MSG_ACK_RESULT, IPCM_GetRequestIndex(pMsg), IPCM_OK };
    73     IPC_SendMsg(pIpcClient, IPCM_TARGET, &aResp[0], sizeof(aResp));
     61    const IPCMMSGRESULT IcpmRes = { { IPCM_MSG_ACK_RESULT, IPCM_GetRequestIndex(pMsg) }, IPCM_OK };
     62    IPC_SendMsg(pIpcClient, IPCM_TARGET, &IcpmRes, sizeof(IcpmRes));
    7463}
    7564
     
    7867    Log(("got CLIENT_HELLO\n"));
    7968
    80     const uint32_t aResp[3] = { IPCM_MSG_ACK_CLIENT_ID, IPCM_GetRequestIndex(pMsg), ipcdClientGetId(pIpcClient) };
    81     IPC_SendMsg(pIpcClient, IPCM_TARGET, &aResp[0], sizeof(aResp));
     69    const IPCMMSGCLIENTID IcmpRes = { { IPCM_MSG_ACK_CLIENT_ID, IPCM_GetRequestIndex(pMsg) }, ipcdClientGetId(pIpcClient) };
     70    IPC_SendMsg(pIpcClient, IPCM_TARGET, &IcmpRes, sizeof(IcmpRes));
    8271
    8372    //
     
    113102        status = IPCM_ERROR_INVALID_ARG;
    114103
    115     const uint32_t aResp[3] = { IPCM_MSG_ACK_RESULT, requestIndex, (uint32_t)status };
    116     IPC_SendMsg(pIpcClient, IPCM_TARGET, &aResp[0], sizeof(aResp));
     104    const IPCMMSGRESULT IcpmRes = { { IPCM_MSG_ACK_RESULT, requestIndex }, status };
     105    IPC_SendMsg(pIpcClient, IPCM_TARGET, &IcpmRes, sizeof(IcpmRes));
    117106}
    118107
     
    136125        status = IPCM_ERROR_INVALID_ARG;
    137126
    138     const uint32_t aResp[3] = { IPCM_MSG_ACK_RESULT, IPCM_GetRequestIndex(pMsg), (uint32_t)status  };
    139     IPC_SendMsg(pIpcClient, IPCM_TARGET, &aResp[0], sizeof(aResp));
     127    const IPCMMSGRESULT IcpmRes = { { IPCM_MSG_ACK_RESULT, requestIndex }, status };
     128    IPC_SendMsg(pIpcClient, IPCM_TARGET, &IcpmRes, sizeof(IcpmRes));
    140129}
    141130
     
    156145        ipcdClientAddTarget(pIpcClient, pidTarget);
    157146
    158     const uint32_t aResp[3] = { IPCM_MSG_ACK_RESULT, IPCM_GetRequestIndex(pMsg), (uint32_t)status };
    159     IPC_SendMsg(pIpcClient, IPCM_TARGET, &aResp[0], sizeof(aResp));
     147    const IPCMMSGRESULT IcpmRes = { { IPCM_MSG_ACK_RESULT, requestIndex }, status };
     148    IPC_SendMsg(pIpcClient, IPCM_TARGET, &IcpmRes, sizeof(IcpmRes));
    160149}
    161150
     
    174163    }
    175164
    176     const uint32_t aResp[3] = { IPCM_MSG_ACK_RESULT, IPCM_GetRequestIndex(pMsg), (uint32_t)status };
    177     IPC_SendMsg(pIpcClient, IPCM_TARGET, &aResp[0], sizeof(aResp));
     165    const IPCMMSGRESULT IcpmRes = { { IPCM_MSG_ACK_RESULT, requestIndex }, status };
     166    IPC_SendMsg(pIpcClient, IPCM_TARGET, &IcpmRes, sizeof(IcpmRes));
    178167}
    179168
     
    189178    {
    190179        Log(("  client exists w/ ID = %u\n", ipcdClientGetId(pIpcClientResult)));
    191         const uint32_t aResp[3] = { IPCM_MSG_ACK_CLIENT_ID, requestIndex, ipcdClientGetId(pIpcClientResult) };
    192         IPC_SendMsg(pIpcClient, IPCM_TARGET, &aResp[0], sizeof(aResp));
     180        const IPCMMSGCLIENTID IcmpRes = { { IPCM_MSG_ACK_CLIENT_ID, requestIndex }, ipcdClientGetId(pIpcClientResult) };
     181        IPC_SendMsg(pIpcClient, IPCM_TARGET, &IcmpRes, sizeof(IcmpRes));
    193182    }
    194183    else
    195184    {
    196185        Log(("  client does not exist\n"));
    197         const uint32_t aResp[3] = { IPCM_MSG_ACK_RESULT, requestIndex, (uint32_t)IPCM_ERROR_NO_CLIENT };
    198         IPC_SendMsg(pIpcClient, IPCM_TARGET, &aResp[0], sizeof(aResp));
     186        const IPCMMSGRESULT IcpmRes = { { IPCM_MSG_ACK_RESULT, requestIndex }, IPCM_ERROR_NO_CLIENT };
     187        IPC_SendMsg(pIpcClient, IPCM_TARGET, &IcpmRes, sizeof(IcpmRes));
    199188    }
    200189}
     
    203192{
    204193    Log(("got FORWARD\n"));
     194
     195    PRUint32 requestIndex = IPCM_GetRequestIndex(pMsg);
    205196
    206197    uint32_t idClient = *(uint32_t *)((uint8_t *)IPCMsgGetPayload(pMsg) + 2 * sizeof(uint32_t));
     
    209200    {
    210201        Log(("  destination client not found!\n"));
    211         const uint32_t aResp[3] = { IPCM_MSG_ACK_RESULT, IPCM_GetRequestIndex(pMsg), (uint32_t)IPCM_ERROR_NO_CLIENT };
    212         IPC_SendMsg(pIpcClient, IPCM_TARGET, &aResp[0], sizeof(aResp));
     202        const IPCMMSGRESULT IcpmRes = { { IPCM_MSG_ACK_RESULT, requestIndex }, IPCM_ERROR_NO_CLIENT };
     203        IPC_SendMsg(pIpcClient, IPCM_TARGET, &IcpmRes, sizeof(IcpmRes));
    213204        return;
    214205    }
    215206    // inform client that its message will be forwarded
    216     const uint32_t aResp[3] = { IPCM_MSG_ACK_RESULT, IPCM_GetRequestIndex(pMsg), IPCM_OK };
    217     IPC_SendMsg(pIpcClient, IPCM_TARGET, &aResp[0], sizeof(aResp));
     207    const IPCMMSGRESULT IcpmRes = { { IPCM_MSG_ACK_RESULT, requestIndex }, IPCM_OK };
     208    IPC_SendMsg(pIpcClient, IPCM_TARGET, &IcpmRes, sizeof(IcpmRes));
    218209
    219210    uint32_t aIpcmFwdHdr[3] = { IPCM_MSG_PSH_FORWARD, IPCM_NewRequestIndex(), ipcdClientGetId(pIpcClient) };
  • trunk/src/libs/xpcom18a4/ipc/ipcd/daemon/src/ipcd.cpp

    r103378 r103472  
    116116    const char lockName[] = "lock";
    117117
    118     int dirLen = strlen(baseDir);
    119     int len = dirLen            // baseDir
    120             + 1                 // "/"
    121             + sizeof(lockName); // "lock"
     118    size_t dirLen = strlen(baseDir);
     119    size_t len = dirLen            // baseDir
     120               + 1                 // "/"
     121               + sizeof(lockName); // "lock"
    122122
    123123    //
     
    410410    // remember if client is expecting SYNC_REPLY.  we'll add that flag to the
    411411    // next message sent to the client.
    412     if (IPCMsgIsFlagSet(pMsg, IPC_MSG_FLAG_SYNC_QUERY))
     412    if (IPCMsgIsFlagSet(pMsg, IPC_MSG_HDR_FLAG_SYNC_QUERY))
    413413    {
    414414        Assert(!ipcdClientGetExpectsSyncReply(pIpcClient));
     
    432432    // add SYNC_REPLY flag to message if client is expecting...
    433433    if (ipcdClientGetExpectsSyncReply(pIpcClient)) {
    434         pMsg->pMsgHdr->u16Flags |= IPC_MSG_FLAG_SYNC_REPLY;
     434        pMsg->pMsgHdr->u16Flags |= IPC_MSG_HDR_FLAG_SYNC_REPLY;
    435435        ipcdClientSetExpectsSyncReply(pIpcClient, false);
    436436    }
     
    591591            // we terminate
    592592            if (status != ELockFileOwner)
    593                 printf("Cannot create a lock file for '%s'.\n"
    594                         "Check permissions.\n", addr.sun_path);
     593                RTMsgError("Cannot create a lock file for '%s'.\n"
     594                           "Check permissions.\n", addr.sun_path);
    595595            return VERR_INVALID_PARAMETER;
    596596        }
  • trunk/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcConfig.cpp

    r102340 r103472  
    5353{
    5454    const char *logName;
    55     int len;
    5655
    5756    char *pszDst = buf;
  • trunk/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcMessageNew.h

    r103378 r103472  
    121121    /** Flag whether the message is complete and the buffer is therefore readonly right now. */
    122122    bool                    fReadonly;
     123    /** Flag whether the message is living on the stack and shouldn't be freed. */
     124    bool                    fStack;
     125    /** Some metadata which is up to the user to use. */
     126    uintptr_t               upUser;
    123127} IPCMSG;
    124128/** Pointer to an IPC message. */
     
    128132
    129133
     134DECLINLINE(PIPCMSGHDR) IPCMsgHdrInit(PIPCMSGHDR pMsgHdr, const nsID &target, size_t cbPayload)
     135{
     136    Assert(cbPayload == (uint32_t)cbPayload);
     137
     138    pMsgHdr->cbMsg      = sizeof(*pMsgHdr) + (uint32_t)cbPayload;
     139    pMsgHdr->u16Version = IPC_MSG_HDR_VERSION;
     140    pMsgHdr->u16Flags   = 0;
     141    pMsgHdr->idTarget   = target;
     142
     143    return pMsgHdr;
     144}
     145
     146
     147DECLINLINE(void) IPCMsgInitStack(PIPCMSG pThis, const nsID &target, const void *pvData, size_t cbData)
     148{
     149    pThis->fStack              = true;
     150    pThis->fReadonly           = true;
     151    pThis->pbBuf               = (uint8_t *)pvData;
     152    pThis->cbBuf               = sizeof(*pThis->pMsgHdr) + cbData;
     153    pThis->pMsgHdr             = (PIPCMSGHDR)pThis->pbBuf;
     154    pThis->pMsgHdr->cbMsg      = sizeof(*pThis->pMsgHdr) + cbData;
     155    pThis->pMsgHdr->u16Version = IPC_MSG_HDR_VERSION;
     156    pThis->pMsgHdr->u16Flags   = 0;
     157    pThis->pMsgHdr->idTarget   = target;
     158}
     159
     160
    130161DECLINLINE(int) IPCMsgInit(PIPCMSG pThis, size_t cbBuf)
    131162{
     
    155186    if (RT_UNLIKELY(!pThis))
    156187        return NULL;
     188
     189    pThis->fStack = false;
    157190
    158191    if (cbMsg)
     
    180213DECLINLINE(void) IPCMsgFree(PIPCMSG pThis, bool fFreeStruct)
    181214{
     215    /* Stack based messages are never freed. */
     216    if (pThis->fStack)
     217        return;
     218
    182219    if (pThis->pbBuf)
    183220        RTMemFree(pThis->pbBuf);
     
    316353
    317354/**
     355 * Clears the given flag in the message header.
     356 *
     357 * @param   pThis       The IPC message.
     358 * @param   fFlag       The flag to clear.
     359 */
     360DECLINLINE(void) IPCMsgClearFlag(PIPCMSG pThis, uint16_t fFlag)
     361{
     362    pThis->pMsgHdr->u16Flags &= ~fFlag;
     363}
     364
     365
     366/**
    318367 * Init worker for a given message frame.
    319368 *
     
    373422DECLINLINE(int) IPCMsgInitSg(PIPCMSG pThis, const nsID &target, size_t cbTotal, PCRTSGSEG paSegs, uint32_t cSegs)
    374423{
     424    Assert(!pThis->fStack);
     425
    375426    uint32_t cbMsg = sizeof(*pThis->pMsgHdr) + cbTotal;
    376427    if (pThis->cbBuf < cbMsg)
     
    389440
    390441
     442DECLINLINE(PIPCMSG) IPCMsgClone(PCIPCMSG pThis)
     443{
     444    size_t cbPayload = pThis->pMsgHdr->cbMsg - sizeof(*pThis->pMsgHdr);
     445    PIPCMSG pClone = IPCMsgAlloc(cbPayload);
     446    if (!pClone)
     447        return NULL;
     448
     449    pClone->pMsgHdr = (PIPCMSGHDR)pClone->pbBuf;
     450    *pClone->pMsgHdr = *pThis->pMsgHdr;
     451    pClone->upUser = pThis->upUser;
     452    memcpy(pClone->pMsgHdr + 1, pThis->pMsgHdr + 1, cbPayload);
     453    return pClone;
     454}
     455
     456
     457DECLINLINE(int) IPCMsgCloneWithMsg(PCIPCMSG pThis, PIPCMSG pClone)
     458{
     459    RTSGSEG Seg;
     460    Seg.pvSeg = (void *)IPCMsgGetPayload(pThis);
     461    Seg.cbSeg = IPCMsgGetPayloadSize(pThis);
     462
     463    pClone->upUser = pThis->upUser;
     464    return IPCMsgInitSg(pClone, *IPCMsgGetTarget(pThis),
     465                        Seg.cbSeg, &Seg, 1 /*cSeg*/);
     466}
     467
     468
    391469/**
    392470 * Reads data for the given message from the given buffer.
     
    401479DECLINLINE(int) IPCMsgReadFrom(PIPCMSG pThis, const void *pvData, size_t cbData, size_t *pcbRead, bool *pfDone)
    402480{
     481    Assert(!pThis->fStack);
     482
    403483    size_t cbHdrRead = 0;
    404484    if (!pThis->pMsgHdr)
  • trunk/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcm.cpp

    r101966 r103472  
    3636 * ***** END LICENSE BLOCK ***** */
    3737
    38 #include <string.h>
    3938#include "ipcm.h"
    4039
     
    4948};
    5049
    51 PRUint32
    52 IPCM_NewRequestIndex()
     50DECLHIDDEN(uint32_t) IPCM_NewRequestIndex()
    5351{
    5452    static volatile uint32_t sRequestIndex = 0;
    5553    return ASMAtomicIncU32(&sRequestIndex);
    5654}
    57 
    58 #if 0
    59 
    60 //
    61 // MSG_TYPE values
    62 //
    63 const PRUint32 ipcmMessagePing::MSG_TYPE = IPCM_MSG_TYPE_PING;
    64 const PRUint32 ipcmMessageError::MSG_TYPE = IPCM_MSG_TYPE_ERROR;
    65 const PRUint32 ipcmMessageClientHello::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_HELLO;
    66 const PRUint32 ipcmMessageClientID::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_ID;
    67 const PRUint32 ipcmMessageClientInfo::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_INFO;
    68 const PRUint32 ipcmMessageClientAddName::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_ADD_NAME;
    69 const PRUint32 ipcmMessageClientDelName::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_DEL_NAME;
    70 const PRUint32 ipcmMessageClientAddTarget::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_ADD_TARGET;
    71 const PRUint32 ipcmMessageClientDelTarget::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_DEL_TARGET;
    72 const PRUint32 ipcmMessageQueryClientByName::MSG_TYPE = IPCM_MSG_TYPE_QUERY_CLIENT_BY_NAME;
    73 const PRUint32 ipcmMessageQueryClientInfo::MSG_TYPE = IPCM_MSG_TYPE_QUERY_CLIENT_INFO;
    74 const PRUint32 ipcmMessageForward::MSG_TYPE = IPCM_MSG_TYPE_FORWARD;
    75 const PRUint32 ipcmMessageClientStatus::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_STATUS;
    76 
    77 //
    78 // CLIENT_INFO message
    79 //
    80 //  +-----------------------------------------+
    81 //  | DWORD : MSG_TYPE                        |
    82 //  +--------------------+--------------------+
    83 //  | DWORD : clientID                        |
    84 //  +--------------------+--------------------+
    85 //  | DWORD : requestIndex                    |
    86 //  +--------------------+--------------------+
    87 //  | WORD : nameStart   | WORD : nameCount   |
    88 //  +--------------------+--------------------+
    89 //  | WORD : targetStart | WORD : targetCount |
    90 //  +--------------------+--------------------+
    91 //  | name[0]            | (null byte)        |
    92 //  +--------------------+--------------------+
    93 //  .                    .                    .
    94 //  .                    .                    .
    95 //  +--------------------+--------------------+
    96 //  | name[count - 1]    | (null byte)        |
    97 //  +--------------------+--------------------+
    98 //  | target[0]                               |
    99 //  +-----------------------------------------+
    100 //  .                    .                    .
    101 //  .                    .                    .
    102 //  +-----------------------------------------+
    103 //  | target[count - 1]                       |
    104 //  +-----------------------------------------+
    105 //
    106 
    107 struct ipcmClientInfoHeader
    108 {
    109     PRUint32 mType;
    110     PRUint32 mID;
    111     PRUint32 mRequestIndex;
    112     PRUint16 mNameStart;
    113     PRUint16 mNameCount;
    114     PRUint16 mTargetStart;
    115     PRUint16 mTargetCount;
    116 };
    117 
    118 ipcmMessageClientInfo::ipcmMessageClientInfo(PRUint32 cID, PRUint32 rIdx, const char *names[], const nsID *targets[])
    119 {
    120     ipcmClientInfoHeader hdr = {0};
    121 
    122     hdr.mType = MSG_TYPE;
    123     hdr.mID = cID;
    124     hdr.mRequestIndex = rIdx;
    125     hdr.mNameStart = sizeof(hdr);
    126 
    127     PRUint32 i, namesLen = 0;
    128 
    129     i = 0;
    130     while (names[i]) {
    131         namesLen += (strlen(names[i]) + 1);
    132         ++hdr.mNameCount;
    133         ++i;
    134     }
    135 
    136     i = 0;
    137     while (targets[i]) {
    138         ++hdr.mTargetCount;
    139         ++i;
    140     }
    141 
    142     //
    143     // compute target array starting offset
    144     //
    145     hdr.mTargetStart = hdr.mNameStart + namesLen;
    146 
    147     //
    148     // compute message length
    149     //
    150     PRUint32 dataLen = sizeof(hdr) + namesLen + hdr.mTargetCount * sizeof(nsID);
    151 
    152     Init(IPCM_TARGET, NULL, dataLen);
    153    
    154     //
    155     // write message data
    156     //
    157     SetData(0, (const char *) &hdr, sizeof(hdr));
    158 
    159     PRUint32 offset = sizeof(hdr);
    160 
    161     for (i = 0; names[i]; ++i) {
    162         PRUint32 len = strlen(names[i]) + 1;
    163         SetData(offset, names[i], len);
    164         offset += len;
    165     }
    166 
    167     for (i = 0; targets[i]; ++i) {
    168         PRUint32 len = sizeof(nsID);
    169         SetData(offset, (const char *) targets[i], len);
    170         offset += len;
    171     }
    172 }
    173 
    174 PRUint32
    175 ipcmMessageClientInfo::ClientID() const
    176 {
    177     ipcmClientInfoHeader *hdr = (ipcmClientInfoHeader *) Data();
    178     return hdr->mID;
    179 }
    180 
    181 PRUint32
    182 ipcmMessageClientInfo::RequestIndex() const
    183 {
    184     ipcmClientInfoHeader *hdr = (ipcmClientInfoHeader *) Data();
    185     return hdr->mRequestIndex;
    186 }
    187 
    188 PRUint32
    189 ipcmMessageClientInfo::NameCount() const
    190 {
    191     ipcmClientInfoHeader *hdr = (ipcmClientInfoHeader *) Data();
    192     return hdr->mNameCount;
    193 }
    194 
    195 PRUint32
    196 ipcmMessageClientInfo::TargetCount() const
    197 {
    198     ipcmClientInfoHeader *hdr = (ipcmClientInfoHeader *) Data();
    199     return hdr->mTargetCount;
    200 }
    201 
    202 const char *
    203 ipcmMessageClientInfo::NextName(const char *name) const
    204 {
    205     ipcmClientInfoHeader *hdr = (ipcmClientInfoHeader *) Data();
    206 
    207     if (!name)
    208         return (const char *) hdr + hdr->mNameStart;
    209 
    210     name += strlen(name) + 1;
    211     if (name == (const char *) hdr + hdr->mTargetStart)
    212         name = NULL;
    213     return name;
    214 }
    215 
    216 const nsID *
    217 ipcmMessageClientInfo::NextTarget(const nsID *target) const
    218 {
    219     ipcmClientInfoHeader *hdr = (ipcmClientInfoHeader *) Data();
    220 
    221     if (!target)
    222         return (const nsID *) (Data() + hdr->mTargetStart);
    223 
    224     if (++target == (const nsID *) (MsgBuf() + MsgLen()))
    225         target = NULL;
    226     return target;
    227 }
    228 #endif
    229 
    230 //
    231 // FORWARD message
    232 //
    233 //  +-------------------------+
    234 //  | DWORD : MSG_TYPE        |
    235 //  +-------------------------+
    236 //  | clientID                |
    237 //  +-------------------------+
    238 //  | innerMsgHeader          |
    239 //  +-------------------------+
    240 //  | innerMsgData            |
    241 //  +-------------------------+
    242 //
    243 
    244 ipcmMessageForward::ipcmMessageForward(PRUint32 type,
    245                                        PRUint32 cID,
    246                                        const nsID &target,
    247                                        const char *data,
    248                                        PRUint32 dataLen)
    249 {
    250     int len = sizeof(ipcmMessageHeader) +  // IPCM header
    251               sizeof(cID) +                // cID
    252               IPC_MSG_HEADER_SIZE +        // innerMsgHeader
    253               dataLen;                     // innerMsgData
    254 
    255     Init(IPCM_TARGET, NULL, len);
    256 
    257     ipcmMessageHeader ipcmHdr =
    258         { type, IPCM_NewRequestIndex() };
    259 
    260     SetData(0, (char *) &ipcmHdr, sizeof(ipcmHdr));
    261     SetData(sizeof(ipcmHdr), (char *) &cID, sizeof(cID));
    262 
    263     ipcMessageHeader hdr;
    264     hdr.mLen = IPC_MSG_HEADER_SIZE + dataLen;
    265     hdr.mVersion = IPC_MSG_VERSION;
    266     hdr.mFlags = 0;
    267     hdr.mTarget = target;
    268 
    269     SetData(sizeof(ipcmHdr) + sizeof(cID), (char *) &hdr, IPC_MSG_HEADER_SIZE);
    270     if (data)
    271         SetInnerData(0, data, dataLen);
    272 }
    273 
    274 void
    275 ipcmMessageForward::SetInnerData(PRUint32 offset, const char *data, PRUint32 dataLen)
    276 {
    277     SetData(sizeof(ipcmMessageHeader) + 4 + IPC_MSG_HEADER_SIZE + offset, data, dataLen);
    278 }
    279 
    280 PRUint32
    281 ipcmMessageForward::ClientID() const
    282 {
    283     return ((PRUint32 *) Data())[2];
    284 }
    285 
    286 const nsID &
    287 ipcmMessageForward::InnerTarget() const
    288 {
    289     ipcMessageHeader *hdr = (ipcMessageHeader *) (Data() + 12);
    290     return hdr->mTarget;
    291 }
    292 
    293 const char *
    294 ipcmMessageForward::InnerData() const
    295 {
    296     return Data() + 12 + IPC_MSG_HEADER_SIZE;
    297 }
    298 
    299 PRUint32
    300 ipcmMessageForward::InnerDataLen() const
    301 {
    302     ipcMessageHeader *hdr = (ipcMessageHeader *) (Data() + 12);
    303     return hdr->mLen - IPC_MSG_HEADER_SIZE;
    304 }
  • trunk/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcm.h

    r103378 r103472  
    4141#include <iprt/assertcompile.h>
    4242
    43 #include "ipcMessage.h"
    44 #include "ipcMessagePrimitives.h"
     43#include "ipcMessageNew.h"
    4544
    4645//-----------------------------------------------------------------------------
     
    115114// IPCM header
    116115//
    117 struct ipcmMessageHeader
    118 {
    119     PRUint32 mType;
    120     PRUint32 mRequestIndex;
    121 };
    122 AssertCompileSize(struct ipcmMessageHeader, 8);
    123 
    124 //
    125 // returns IPCM message type.
    126 //
    127 static inline int
    128 IPCM_GetType(const ipcMessage *msg)
    129 {
    130     return ((const ipcmMessageHeader *) msg->Data())->mType;
    131 }
    132 
    133 //
    134 // return IPCM message request index.
    135 //
    136 static inline PRUint32
    137 IPCM_GetRequestIndex(const ipcMessage *msg)
    138 {
    139     return ((const ipcmMessageHeader *) msg->Data())->mRequestIndex;
    140 }
     116typedef struct IPCMMSGHDR
     117{
     118    uint32_t u32Type;
     119    uint32_t u32RequestIndex;
     120} IPCMMSGHDR;
     121AssertCompileSize(struct IPCMMSGHDR, 8);
     122/** Pointer to an IPCM header. */
     123typedef IPCMMSGHDR *PIPCMMSGHDR;
     124/** Pointer to a const IPCM header. */
     125typedef const IPCMMSGHDR *PCIPCMMSGHDR;
     126
     127
     128DECLINLINE(uint32_t) IPCM_GetType(PCIPCMSG pMsg)
     129{
     130    return ((PCIPCMMSGHDR)IPCMsgGetPayload(pMsg))->u32Type;
     131}
     132
     133
     134DECLINLINE(uint32_t) IPCM_GetRequestIndex(PCIPCMSG pMsg)
     135{
     136    return ((PCIPCMMSGHDR)IPCMsgGetPayload(pMsg))->u32RequestIndex;
     137}
     138
    141139
    142140//
    143141// return a request index that is unique to this process.
    144142//
    145 NS_HIDDEN_(PRUint32)
    146 IPCM_NewRequestIndex();
     143DECLHIDDEN(uint32_t) IPCM_NewRequestIndex();
    147144
    148145//-----------------------------------------------------------------------------
     
    322319//
    323320
    324 //-----------------------------------------------------------------------------
    325 
    326 //
    327 // NOTE: This file declares some helper classes that simplify constructing
    328 //       and parsing IPCM messages.  Each class subclasses ipcMessage, but
    329 //       adds no additional member variables.  |operator new| should be used
    330 //       to allocate one of the IPCM helper classes, e.g.:
    331 //
    332 //          ipcMessage *msg = new ipcmMessageClientHello("foo");
    333 //
    334 //       Given an arbitrary ipcMessage, it can be parsed using logic similar
    335 //       to the following:
    336 //
    337 //          void func(const ipcMessage *unknown)
    338 //          {
    339 //            if (unknown->Topic().Equals(IPCM_TARGET)) {
    340 //              if (IPCM_GetMsgType(unknown) == IPCM_MSG_TYPE_CLIENT_ID) {
    341 //                ipcMessageCast<ipcmMessageClientID> msg(unknown);
    342 //                printf("Client ID: %u\n", msg->ClientID());
    343 //              }
    344 //            }
    345 //          }
    346 //
    347 
    348321// REQUESTS
    349322
    350 class ipcmMessagePing : public ipcMessage_DWORD_DWORD
    351 {
    352 public:
    353     ipcmMessagePing()
    354         : ipcMessage_DWORD_DWORD(
    355             IPCM_TARGET,
    356             IPCM_MSG_REQ_PING,
    357             IPCM_NewRequestIndex()) {}
    358 };
    359 
    360 class ipcmMessageForward : public ipcMessage
    361 {
    362 public:
    363     // @param type        the type of this message: IPCM_MSG_{REQ,PSH}_FORWARD
    364     // @param clientID    the client id of the sender or receiver
    365     // @param target      the message target
    366     // @param data        the message data
    367     // @param dataLen     the message data length
    368     ipcmMessageForward(PRUint32 type,
    369                        PRUint32 clientID,
    370                        const nsID &target,
    371                        const char *data,
    372                        PRUint32 dataLen) NS_HIDDEN;
    373 
    374     // set inner message data, constrained to the data length passed
    375     // to this class's constructor.
    376     NS_HIDDEN_(void) SetInnerData(PRUint32 offset, const char *data, PRUint32 dataLen);
    377 
    378     NS_HIDDEN_(PRUint32)     ClientID() const;
    379     NS_HIDDEN_(const nsID &) InnerTarget() const;
    380     NS_HIDDEN_(const char *) InnerData() const;
    381     NS_HIDDEN_(PRUint32)     InnerDataLen() const;
    382 };
    383 
    384 class ipcmMessageClientHello : public ipcMessage_DWORD_DWORD
    385 {
    386 public:
    387     ipcmMessageClientHello()
    388         : ipcMessage_DWORD_DWORD(
    389             IPCM_TARGET,
    390             IPCM_MSG_REQ_CLIENT_HELLO,
    391             IPCM_NewRequestIndex()) {}
    392 };
    393 
    394 class ipcmMessageClientAddName : public ipcMessage_DWORD_DWORD_STR
    395 {
    396 public:
    397     ipcmMessageClientAddName(const char *name)
    398         : ipcMessage_DWORD_DWORD_STR(
    399             IPCM_TARGET,
    400             IPCM_MSG_REQ_CLIENT_ADD_NAME,
    401             IPCM_NewRequestIndex(),
    402             name) {}
    403 
    404     const char *Name() const { return Third(); }
    405 };
    406 
    407 class ipcmMessageClientDelName : public ipcMessage_DWORD_DWORD_STR
    408 {
    409 public:
    410     ipcmMessageClientDelName(const char *name)
    411         : ipcMessage_DWORD_DWORD_STR(
    412             IPCM_TARGET,
    413             IPCM_MSG_REQ_CLIENT_DEL_NAME,
    414             IPCM_NewRequestIndex(),
    415             name) {}
    416 
    417     const char *Name() const { return Third(); }
    418 };
    419 
    420 class ipcmMessageClientAddTarget : public ipcMessage_DWORD_DWORD_ID
    421 {
    422 public:
    423     ipcmMessageClientAddTarget(const nsID &target)
    424         : ipcMessage_DWORD_DWORD_ID(
    425             IPCM_TARGET,
    426             IPCM_MSG_REQ_CLIENT_ADD_TARGET,
    427             IPCM_NewRequestIndex(),
    428             target) {}
    429 
    430     const nsID &Target() const { return Third(); }
    431 };
    432 
    433 class ipcmMessageClientDelTarget : public ipcMessage_DWORD_DWORD_ID
    434 {
    435 public:
    436     ipcmMessageClientDelTarget(const nsID &target)
    437         : ipcMessage_DWORD_DWORD_ID(
    438             IPCM_TARGET,
    439             IPCM_MSG_REQ_CLIENT_ADD_TARGET,
    440             IPCM_NewRequestIndex(),
    441             target) {}
    442 
    443     const nsID &Target() const { return Third(); }
    444 };
    445 
    446 class ipcmMessageQueryClientByName : public ipcMessage_DWORD_DWORD_STR
    447 {
    448 public:
    449     ipcmMessageQueryClientByName(const char *name)
    450         : ipcMessage_DWORD_DWORD_STR(
    451             IPCM_TARGET,
    452             IPCM_MSG_REQ_QUERY_CLIENT_BY_NAME,
    453             IPCM_NewRequestIndex(),
    454             name) {}
    455 
    456     const char *Name() const { return Third(); }
    457     PRUint32 RequestIndex() const { return Second(); }
    458 };
     323/** The ping message consists of just the header. */
     324typedef IPCMMSGHDR IPCMMSGPING;
     325typedef IPCMMSGPING *PIPCMMSGPING;
     326
     327DECLINLINE(void) IPCMMsgPingInit(PIPCMMSGPING pThis)
     328{
     329    pThis->u32Type         = IPCM_MSG_REQ_PING;
     330    pThis->u32RequestIndex = IPCM_NewRequestIndex();
     331}
     332
     333
     334/** The client hello message consists of just the header. */
     335typedef IPCMMSGHDR IPCMMSGCLIENTHELLO;
     336typedef IPCMMSGCLIENTHELLO *PIPCMMSGCLIENTHELLO;
     337
     338DECLINLINE(void) IPCMMsgClientHelloInit(PIPCMMSGCLIENTHELLO pThis)
     339{
     340    pThis->u32Type         = IPCM_MSG_REQ_CLIENT_HELLO;
     341    pThis->u32RequestIndex = IPCM_NewRequestIndex();
     342}
     343
     344
     345typedef struct IPCMMSGFORWARD
     346{
     347    IPCMMSGHDR          Hdr;
     348    uint32_t            u32ClientId;
     349} IPCMMSGFORWARD;
     350AssertCompileSize(IPCMMSGFORWARD, 3 * sizeof(uint32_t));
     351typedef IPCMMSGFORWARD *PIPCMMSGFORWARD;
     352typedef const IPCMMSGFORWARD *PCIPCMMSGFORWARD;
     353
     354
     355DECLINLINE(int) ipcmMsgInitHdrStr(PIPCMSG pMsg, uint32_t u32Type, const char *psz)
     356{
     357    size_t cbStr = strlen(psz) + 1; /* Includes terminator. */
     358    const IPCMMSGHDR Hdr = { u32Type, IPCM_NewRequestIndex() };
     359    RTSGSEG aSegs[2];
     360
     361    aSegs[0].pvSeg = (void *)&Hdr;
     362    aSegs[0].cbSeg = sizeof(Hdr);
     363
     364    aSegs[1].pvSeg = (void *)psz;
     365    aSegs[1].cbSeg = cbStr;
     366    return IPCMsgInitSg(pMsg, IPCM_TARGET, cbStr + sizeof(Hdr), &aSegs[0], RT_ELEMENTS(aSegs));
     367}
     368
     369
     370DECLINLINE(int) IPCMMsgClientAddNameInit(PIPCMSG pMsg, const char *pszName)
     371{
     372    return ipcmMsgInitHdrStr(pMsg, IPCM_MSG_REQ_CLIENT_ADD_NAME, pszName);
     373}
     374
     375
     376DECLINLINE(int) IPCMMsgClientDelNameInit(PIPCMSG pMsg, const char *pszName)
     377{
     378    return ipcmMsgInitHdrStr(pMsg, IPCM_MSG_REQ_CLIENT_DEL_NAME, pszName);
     379}
     380
     381
     382typedef struct IPCMMSGCLIENTADDDELTARGET
     383{
     384    IPCMMSGHDR          Hdr;
     385    nsID                idTarget;
     386} IPCMMSGCLIENTADDDELTARGET;
     387AssertCompileSize(IPCMMSGCLIENTADDDELTARGET, 2 * sizeof(uint32_t) + sizeof(nsID));
     388typedef IPCMMSGCLIENTADDDELTARGET *PIPCMMSGCLIENTADDDELTARGET;
     389typedef const IPCMMSGCLIENTADDDELTARGET *PCIPCMMSGCLIENTADDDELTARGET;
     390
     391DECLINLINE(void) IPCMMsgAddTargetInit(PIPCMMSGCLIENTADDDELTARGET pThis, const nsID &target)
     392{
     393    pThis->Hdr.u32Type         = IPCM_MSG_REQ_CLIENT_ADD_TARGET;
     394    pThis->Hdr.u32RequestIndex = IPCM_NewRequestIndex();
     395    pThis->idTarget            = target;
     396}
     397
     398
     399DECLINLINE(void) IPCMMsgDelTargetInit(PIPCMMSGCLIENTADDDELTARGET pThis, const nsID &target)
     400{
     401    pThis->Hdr.u32Type         = IPCM_MSG_REQ_CLIENT_DEL_TARGET;
     402    pThis->Hdr.u32RequestIndex = IPCM_NewRequestIndex();
     403    pThis->idTarget            = target;
     404}
     405
     406
     407DECLINLINE(int) IPCMMsgQueryClientByNameInit(PIPCMSG pMsg, const char *pszName)
     408{
     409    return ipcmMsgInitHdrStr(pMsg, IPCM_MSG_REQ_QUERY_CLIENT_BY_NAME, pszName);
     410}
     411
    459412
    460413// ACKNOWLEDGEMENTS
    461414
    462 class ipcmMessageResult : public ipcMessage_DWORD_DWORD_DWORD
    463 {
    464 public:
    465     ipcmMessageResult(PRUint32 requestIndex, PRInt32 status)
    466         : ipcMessage_DWORD_DWORD_DWORD(
    467             IPCM_TARGET,
    468             IPCM_MSG_ACK_RESULT,
    469             requestIndex,
    470             (PRUint32) status) {}
    471 
    472     PRInt32 Status() const { return (PRInt32) Third(); }
    473 };
    474 
    475 class ipcmMessageClientID : public ipcMessage_DWORD_DWORD_DWORD
    476 {
    477 public:
    478     ipcmMessageClientID(PRUint32 requestIndex, PRUint32 clientID)
    479         : ipcMessage_DWORD_DWORD_DWORD(
    480             IPCM_TARGET,
    481             IPCM_MSG_ACK_CLIENT_ID,
    482             requestIndex,
    483             clientID) {}
    484 
    485     PRUint32 ClientID() const { return Third(); }
    486 };
     415typedef struct IPCMMSGRESULT
     416{
     417    IPCMMSGHDR          Hdr;
     418    int32_t             i32Status;
     419} IPCMMSGRESULT;
     420AssertCompileSize(IPCMMSGRESULT, 3 * sizeof(uint32_t));
     421typedef IPCMMSGRESULT *PIPCMMSGRESULT;
     422typedef const IPCMMSGRESULT *PCIPCMMSGRESULT;
     423
     424typedef struct IPCMMSGCLIENTID
     425{
     426    IPCMMSGHDR          Hdr;
     427    uint32_t            u32ClientId;
     428} IPCMMSGCLIENTID;
     429AssertCompileSize(IPCMMSGCLIENTID, 3 * sizeof(uint32_t));
     430typedef IPCMMSGCLIENTID *PIPCMMSGCLIENTID;
     431typedef const IPCMMSGCLIENTID *PCIPCMMSGCLIENTID;
     432
    487433
    488434// PUSH MESSAGES
    489435
    490 class ipcmMessageClientState : public ipcMessage_DWORD_DWORD_DWORD_DWORD
    491 {
    492 public:
    493     ipcmMessageClientState(PRUint32 clientID, PRUint32 clientStatus)
    494         : ipcMessage_DWORD_DWORD_DWORD_DWORD(
    495             IPCM_TARGET,
    496             IPCM_MSG_PSH_CLIENT_STATE,
    497             0,
    498             clientID,
    499             clientStatus) {}
    500 
    501     PRUint32 ClientID() const { return Third(); }
    502     PRUint32 ClientState() const { return Fourth(); }
    503 };
     436typedef struct IPCMMSGCLIENTSTATE
     437{
     438    IPCMMSGHDR          Hdr;
     439    uint32_t            u32ClientId;
     440    uint32_t            u32ClientStatus;
     441} IPCMMSGCLIENTSTATE;
     442AssertCompileSize(IPCMMSGCLIENTSTATE, 4 * sizeof(uint32_t));
     443typedef IPCMMSGCLIENTSTATE *PIPCMMSGCLIENTSTATE;
     444typedef const IPCMMSGCLIENTSTATE *PCIPCMMSGCLIENTSTATE;
     445
     446/**
     447 * Helper structure for stack based messages.
     448 */
     449typedef struct IPCMMSGSTACK
     450{
     451    IPCMSGHDR                       Hdr;
     452    union
     453    {
     454        IPCMMSGHDR                  Hdr;
     455        IPCMMSGPING                 Ping;
     456        IPCMMSGCLIENTHELLO          ClientHello;
     457        IPCMMSGCLIENTADDDELTARGET   AddDelTarget;
     458        IPCMMSGRESULT               Result;
     459        IPCMMSGCLIENTID             ClientId;
     460        IPCMMSGCLIENTSTATE          ClientState;
     461    } Ipcm;
     462} IPCMMSGSTACK;
    504463
    505464#endif // !ipcm_h__
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