VirtualBox

Ignore:
Timestamp:
Nov 10, 2023 1:27:03 PM (15 months ago)
Author:
vboxsync
Message:

libs/xpcom/ipc/ipcd/daemon: Rewrite the IPC daemon code to move away from NSPR and use IPRT, bugref:10545

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

Legend:

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

    r101933 r102062  
    3535 *
    3636 * ***** END LICENSE BLOCK ***** */
    37 
    38 #include "ipcLog.h"
     37#define LOG_GROUP LOG_GROUP_IPC
     38#include <iprt/assert.h>
     39#include <iprt/errcore.h>
     40#include <iprt/poll.h>
     41#include <VBox/log.h>
     42
    3943#include "ipcClient.h"
    4044#include "ipcMessage.h"
     
    4246#include "ipcm.h"
    4347
    44 #if defined(XP_UNIX) || defined(XP_OS2)
    45 #include "prio.h"
    46 #endif
    47 
    4848PRUint32 ipcClient::gLastID = 0;
    4949
     
    5555//
    5656void
    57 ipcClient::Init()
     57ipcClient::Init(uint32_t idPoll, RTSOCKET hSock)
    5858{
    5959    mID = ++gLastID;
     
    6161    // every client must be able to handle IPCM messages.
    6262    mTargets.Append(IPCM_TARGET);
     63
     64    m_hSock  = hSock;
     65    m_idPoll = idPoll;
     66    m_fUsed  = true;
    6367
    6468    // although it is tempting to fire off the NotifyClientUp event at this
     
    7377ipcClient::Finalize()
    7478{
     79    RTSocketClose(m_hSock);
     80    m_hSock = NIL_RTSOCKET;
     81
    7582    IPC_NotifyClientDown(this);
    7683
     
    7885    mTargets.DeleteAll();
    7986
    80 #if defined(XP_UNIX) || defined(XP_OS2)
    8187    mInMsg.Reset();
    8288    mOutMsgQ.DeleteAll();
    83 #endif
     89    m_fUsed = false;
    8490}
    8591
     
    8793ipcClient::AddName(const char *name)
    8894{
    89     LOG(("adding client name: %s\n", name));
     95    LogFlowFunc(("adding client name: %s\n", name));
    9096
    9197    if (HasName(name))
     
    98104ipcClient::DelName(const char *name)
    99105{
    100     LOG(("deleting client name: %s\n", name));
     106    LogFlowFunc(("deleting client name: %s\n", name));
    101107
    102108    return mNames.FindAndDelete(name);
     
    106112ipcClient::AddTarget(const nsID &target)
    107113{
    108     LOG(("adding client target\n"));
     114    LogFlowFunc(("adding client target\n"));
    109115
    110116    if (HasTarget(target))
     
    117123ipcClient::DelTarget(const nsID &target)
    118124{
    119     LOG(("deleting client target\n"));
     125    LogFlowFunc(("deleting client target\n"));
    120126
    121127    //
     
    128134}
    129135
    130 #if defined(XP_UNIX) || defined(XP_OS2)
    131 
    132136//
    133137// called to process a client socket
    134138//
    135139// params:
    136 //   fd         - the client socket
    137140//   poll_flags - the state of the client socket
    138141//
     
    143146//
    144147int
    145 ipcClient::Process(PRFileDesc *fd, int inFlags)
    146 {
    147     if (inFlags & (PR_POLL_ERR    | PR_POLL_HUP |
    148                    PR_POLL_EXCEPT | PR_POLL_NVAL)) {
    149         LOG(("client socket appears to have closed\n"));
     148ipcClient::Process(uint32_t inFlags)
     149{
     150    if (inFlags & RTPOLL_EVT_ERROR)
     151    {
     152        LogFlowFunc(("client socket appears to have closed\n"));
    150153        return 0;
    151154    }
    152155
    153156    // expect to wait for more data
    154     int outFlags = PR_POLL_READ;
    155 
    156     if (inFlags & PR_POLL_READ) {
    157         LOG(("client socket is now readable\n"));
    158 
    159         char buf[1024]; // XXX make this larger?
    160         PRInt32 n;
    161 
    162         // find out how much data is available for reading...
    163         // n = PR_Available(fd);
    164 
    165         n = PR_Read(fd, buf, sizeof(buf));
    166         if (n <= 0)
     157    int outFlags = RTPOLL_EVT_READ;
     158
     159    if (inFlags & RTPOLL_EVT_READ) {
     160        LogFlowFunc(("client socket is now readable\n"));
     161
     162        char buf[_1K];
     163        size_t cbRead = 0;
     164        int vrc = RTSocketReadNB(m_hSock, &buf[0], sizeof(buf), &cbRead);
     165        Assert(vrc != VINF_TRY_AGAIN);
     166
     167        if (RT_FAILURE(vrc) || cbRead == 0)
    167168            return 0; // cancel connection
    168169
    169170        const char *ptr = buf;
    170         while (n) {
     171        while (cbRead)
     172        {
    171173            PRUint32 nread;
    172174            PRBool complete;
    173175
    174             if (mInMsg.ReadFrom(ptr, PRUint32(n), &nread, &complete) == PR_FAILURE) {
    175                 LOG(("message appears to be malformed; dropping client connection\n"));
     176            if (mInMsg.ReadFrom(ptr, PRUint32(cbRead), &nread, &complete) == PR_FAILURE) {
     177                LogFlowFunc(("message appears to be malformed; dropping client connection\n"));
    176178                return 0;
    177179            }
    178180
    179             if (complete) {
     181            if (complete)
     182            {
    180183                IPC_DispatchMsg(this, &mInMsg);
    181184                mInMsg.Reset();
    182185            }
    183186
    184             n -= nread;
    185             ptr += nread;
    186         }
    187     }
    188 
    189     if (inFlags & PR_POLL_WRITE) {
    190         LOG(("client socket is now writable\n"));
     187            cbRead -= nread;
     188            ptr    += nread;
     189        }
     190    }
     191
     192    if (inFlags & RTPOLL_EVT_WRITE) {
     193        LogFlowFunc(("client socket is now writable\n"));
    191194
    192195        if (mOutMsgQ.First())
    193             WriteMsgs(fd);
     196            WriteMsgs();
    194197    }
    195198
    196199    if (mOutMsgQ.First())
    197         outFlags |= PR_POLL_WRITE;
     200        outFlags |= RTPOLL_EVT_WRITE;
    198201
    199202    return outFlags;
     
    204207//
    205208int
    206 ipcClient::WriteMsgs(PRFileDesc *fd)
    207 {
    208     while (mOutMsgQ.First()) {
     209ipcClient::WriteMsgs()
     210{
     211    while (mOutMsgQ.First())
     212    {
    209213        const char *buf = (const char *) mOutMsgQ.First()->MsgBuf();
    210214        PRInt32 bufLen = (PRInt32) mOutMsgQ.First()->MsgLen();
    211215
    212         if (mSendOffset) {
     216        if (mSendOffset)
     217        {
    213218            buf += mSendOffset;
    214219            bufLen -= mSendOffset;
    215220        }
    216221
    217         PRInt32 nw = PR_Write(fd, buf, bufLen);
    218         if (nw <= 0)
     222        size_t cbWritten = 0;
     223        int vrc = RTSocketWriteNB(m_hSock, buf, bufLen, &cbWritten);
     224        if (vrc == VINF_SUCCESS)
     225        { /* likely */ Assert(cbWritten > 0); }
     226        else
     227        {
     228            Assert(   RT_FAILURE(vrc)
     229                   || (vrc == VINF_TRY_AGAIN && cbWritten == 0));
    219230            break;
    220 
    221         LOG(("wrote %d bytes\n", nw));
    222 
    223         if (nw == bufLen) {
     231        }
     232
     233        LogFlowFunc(("wrote %d bytes\n", cbWritten));
     234
     235        if (cbWritten == bufLen)
     236        {
    224237            mOutMsgQ.DeleteFirst();
    225238            mSendOffset = 0;
    226239        }
    227240        else
    228             mSendOffset += nw;
     241            mSendOffset += cbWritten;
    229242    }
    230243
     
    232245}
    233246
    234 #endif
  • trunk/src/libs/xpcom18a4/ipc/ipcd/daemon/src/ipcClient.h

    r7029 r102062  
    3939#define ipcClientUnix_h__
    4040
    41 #include "prio.h"
     41#include <iprt/socket.h>
     42
    4243#include "ipcMessageQ.h"
    4344#include "ipcStringList.h"
    4445#include "ipcIDList.h"
    45 
    46 #ifdef XP_WIN
    47 #include <windows.h>
    48 #endif
    4946
    5047//-----------------------------------------------------------------------------
     
    5956{
    6057public:
    61     void Init();
     58    bool     m_fUsed;
     59    uint32_t m_idPoll;
     60    uint32_t m_fPollEvts;
     61
     62    void Init(uint32_t idPoll, RTSOCKET hSock);
    6263    void Finalize();
    6364
     
    8283    PRBool GetExpectsSyncReply() const     { return mExpectsSyncReply; }
    8384
    84 #ifdef XP_WIN
    85     PRUint32 PID() const { return mPID; }
    86     void SetPID(PRUint32 pid) { mPID = pid; }
    87 
    88     HWND Hwnd() const { return mHwnd; }
    89     void SetHwnd(HWND hwnd) { mHwnd = hwnd; }
    90 #endif
    91 
    92 #if defined(XP_UNIX) || defined(XP_OS2)
    9385    //
    9486    // called to process a client file descriptor.  the value of pollFlags
     
    9688    //
    9789    // returns:
    98     //   0             - to cancel client connection
    99     //   PR_POLL_READ  - to poll for a readable socket
    100     //   PR_POLL_WRITE - to poll for a writable socket
    101     //   (both flags)  - to poll for either a readable or writable socket
     90    //   0                - to cancel client connection
     91    //   RTPOLL_EVT_READ  - to poll for a readable socket
     92    //   RTPOLL_EVT_WRITE - to poll for a writable socket
     93    //   (both flags)     - to poll for either a readable or writable socket
    10294    //
    10395    // the socket is non-blocking.
    10496    //
    105     int Process(PRFileDesc *sockFD, int pollFlags);
     97    int Process(uint32_t pollFlags);
    10698
    10799    //
     
    110102    //
    111103    void EnqueueOutboundMsg(ipcMessage *msg) { mOutMsgQ.Append(msg); }
    112 #endif
    113104
    114105private:
     
    120111    PRBool        mExpectsSyncReply;
    121112
    122 #ifdef XP_WIN
    123     // on windows, we store the PID of the client process to help us determine
    124     // the client from which a message originated.  each message has the PID
    125     // encoded in it.
    126     PRUint32      mPID;
    127 
    128     // the hwnd of the client's message window.
    129     HWND          mHwnd;
    130 #endif
    131 
    132 #if defined(XP_UNIX) || defined(XP_OS2)
    133113    ipcMessage    mInMsg;    // buffer for incoming message
    134114    ipcMessageQ   mOutMsgQ;  // outgoing message queue
     
    137117    PRUint32      mSendOffset;
    138118
     119    /** Client socket. */
     120    RTSOCKET      m_hSock;
     121
    139122    // utility function for writing out messages.
    140     int WriteMsgs(PRFileDesc *fd);
    141 #endif
     123    int WriteMsgs();
    142124};
    143125
  • trunk/src/libs/xpcom18a4/ipc/ipcd/daemon/src/ipcdUnix.cpp

    r102047 r102062  
    3535 *
    3636 * ***** END LICENSE BLOCK ***** */
     37#define LOG_GROUP LOG_GROUP_IPC
     38#include <iprt/assert.h>
     39#include <iprt/errcore.h>
     40#include <iprt/initterm.h>
     41#include <iprt/getopt.h>
     42#include <iprt/message.h>
     43#include <iprt/poll.h>
     44#include <iprt/socket.h>
     45#include <iprt/string.h>
     46#include <VBox/log.h>
    3747
    3848#include <sys/types.h>
    3949#include <sys/stat.h>
     50#include <sys/resource.h>
     51#include <sys/socket.h>
     52#include <sys/un.h>
    4053#include <unistd.h>
    4154#include <fcntl.h>
     
    4457#include <stdlib.h>
    4558#include <string.h>
    46 
    47 #if defined(VBOX) && !defined(XP_OS2)
    48 # include <sys/resource.h>
    49 # include <errno.h>
    50 #endif
    51 
    52 #include <iprt/initterm.h>
    53 #include <iprt/getopt.h>
    54 #include <iprt/message.h>
    55 
    56 #include "prio.h"
    57 #include "prerror.h"
    58 #include "prthread.h"
    59 #include "prinrval.h"
     59#include <errno.h>
     60
    6061#include "plstr.h"
    6162#include "prprf.h"
    6263
    6364#include "ipcConfig.h"
    64 #include "ipcLog.h"
    6565#include "ipcMessage.h"
    6666#include "ipcClient.h"
     
    214214static Status InitDaemonDir(const char *socketPath)
    215215{
    216     LOG(("InitDaemonDir [sock=%s]\n", socketPath));
    217 
    218     char *baseDir = PL_strdup(socketPath);
     216    LogFlowFunc(("InitDaemonDir [sock=%s]\n", socketPath));
     217
     218    char *baseDir = RTStrDup(socketPath);
    219219
    220220    //
     
    232232    Status status = AcquireDaemonLock(baseDir);
    233233
    234     PL_strfree(baseDir);
     234    RTStrFree(baseDir);
    235235
    236236    if (status == EOk) {
     
    243243static void ShutdownDaemonDir()
    244244{
    245     LOG(("ShutdownDaemonDir\n"));
     245    LogFlowFunc(("ShutdownDaemonDir\n"));
    246246
    247247    // deleting directory and files underneath it allows another process
     
    274274// ipcPollList.
    275275//
    276 static ipcClient ipcClientArray[IPC_MAX_CLIENTS + 1];
    277 
    278 //
    279 // element 0 contains the "server socket"
    280 //
    281 static PRPollDesc ipcPollList[IPC_MAX_CLIENTS + 1];
    282 
    283 //-----------------------------------------------------------------------------
    284 
    285 static int AddClient(PRFileDesc *fd)
     276static ipcClient ipcClientArray[IPC_MAX_CLIENTS];
     277
     278static RTPOLLSET g_hPollSet = NIL_RTPOLLSET;
     279
     280//-----------------------------------------------------------------------------
     281
     282static int AddClient(RTPOLLSET hPollSet, RTSOCKET hSock)
    286283{
    287284    if (ipcClientCount == IPC_MAX_CLIENTS) {
    288         LOG(("reached maximum client limit\n"));
     285        LogFlowFunc(("reached maximum client limit\n"));
    289286        return -1;
    290287    }
    291288
    292     int pollCount = ipcClientCount + 1;
    293 
    294     ipcClientArray[pollCount].Init();
    295 
    296     ipcPollList[pollCount].fd = fd;
    297     ipcPollList[pollCount].in_flags = PR_POLL_READ;
    298     ipcPollList[pollCount].out_flags = 0;
    299 
    300     ++ipcClientCount;
    301     return 0;
    302 }
    303 
    304 static int RemoveClient(int clientIndex)
    305 {
    306     PRPollDesc *pd = &ipcPollList[clientIndex];
    307 
    308     PR_Close(pd->fd);
    309 
    310     ipcClientArray[clientIndex].Finalize();
    311 
    312     //
    313     // keep the clients and poll_fds contiguous; move the last one into
    314     // the spot held by the one that is going away.
    315     //
    316     int toIndex = clientIndex;
    317     int fromIndex = ipcClientCount;
    318     if (fromIndex != toIndex) {
    319         memcpy(&ipcClientArray[toIndex], &ipcClientArray[fromIndex], sizeof(ipcClient));
    320         memcpy(&ipcPollList[toIndex], &ipcPollList[fromIndex], sizeof(PRPollDesc));
    321     }
    322 
    323     //
    324     // zero out the old entries.
    325     //
    326     memset(&ipcClientArray[fromIndex], 0, sizeof(ipcClient));
    327     memset(&ipcPollList[fromIndex], 0, sizeof(PRPollDesc));
    328 
     289    /* Find an unused client entry. */
     290    for (uint32_t i = 0; i < RT_ELEMENTS(ipcClientArray); i++)
     291    {
     292        if (!ipcClientArray[i].m_fUsed)
     293        {
     294            ipcClientArray[i].Init(i, hSock);
     295            ipcClientArray[i].m_fPollEvts = RTPOLL_EVT_READ;
     296            int vrc = RTPollSetAddSocket(hPollSet, hSock, RTPOLL_EVT_READ, i);
     297            if (RT_SUCCESS(vrc))
     298            {
     299                ipcClientCount++;
     300                return 0;
     301            }
     302
     303            ipcClientArray[i].Finalize();
     304            break;
     305        }
     306    }
     307
     308    /* Failed to find or set up the IPC client state. */
     309    return -1;
     310}
     311
     312static int RemoveClient(RTPOLLSET hPollSet, uint32_t idClient)
     313{
     314    int vrc = RTPollSetRemove(hPollSet, idClient);
     315    AssertRC(vrc); RT_NOREF(vrc);
     316
     317    ipcClientArray[idClient].Finalize();
    329318    --ipcClientCount;
    330319    return 0;
     
    333322//-----------------------------------------------------------------------------
    334323
    335 static void PollLoop(PRFileDesc *listenFD)
    336 {
    337     // the first element of ipcClientArray is unused.
    338     memset(ipcClientArray, 0, sizeof(ipcClientArray));
    339     ipcClients = ipcClientArray + 1;
    340     ipcClientCount = 0;
    341 
    342     ipcPollList[0].fd = listenFD;
    343     ipcPollList[0].in_flags = PR_POLL_EXCEPT | PR_POLL_READ;
    344 
    345     while (1) {
    346         PRInt32 rv;
    347         PRIntn i;
    348 
    349         int pollCount = ipcClientCount + 1;
    350 
    351         ipcPollList[0].out_flags = 0;
    352 
    353         //
    354         // poll
    355         //
    356         // timeout after 5 minutes.  if no connections after timeout, then
    357         // exit.  this timeout ensures that we don't stay resident when no
    358         // clients are interested in connecting after spawning the daemon.
    359         //
    360         // XXX add #define for timeout value
    361         //
    362         LOG(("calling PR_Poll [pollCount=%d]\n", pollCount));
    363         rv = PR_Poll(ipcPollList, pollCount, PR_SecondsToInterval(60 * 5));
    364         if (rv == -1) {
    365             LOG(("PR_Poll failed [%d]\n", PR_GetError()));
    366             return;
    367         }
    368 
    369         if (rv > 0) {
    370             //
    371             // process clients that are ready
    372             //
    373             for (i = 1; i < pollCount; ++i) {
    374                 if (ipcPollList[i].out_flags != 0) {
    375                     ipcPollList[i].in_flags =
    376                         ipcClientArray[i].Process(ipcPollList[i].fd,
    377                                                   ipcPollList[i].out_flags);
    378                     ipcPollList[i].out_flags = 0;
     324static void PollLoop(RTPOLLSET hPollSet, int fdListen)
     325{
     326    ipcClients = ipcClientArray;
     327
     328    for (;;)
     329    {
     330        LogFlowFunc(("Polling [ipcClientCount=%d]\n", ipcClientCount));
     331        uint32_t idPoll = 0;
     332        uint32_t fEvents = 0;
     333        int vrc = RTPoll(hPollSet, 5 * RT_MS_1MIN, &fEvents, &idPoll);
     334        if (RT_SUCCESS(vrc))
     335        { /* likely */ }
     336        else if (vrc == VERR_TIMEOUT)
     337        {
     338            /* Shutdown if no clients. */
     339            if (ipcClientCount == 0)
     340            {
     341                LogFlowFunc(("shutting down\n"));
     342                break;
     343            }
     344
     345            continue;
     346        }
     347        else
     348        {
     349            LogFlowFunc(("Polling failed with %Rrc\n", vrc));
     350            break;
     351        }
     352
     353        if (idPoll == UINT32_MAX - 1)
     354        {
     355            Assert(fEvents & RTPOLL_EVT_READ);
     356            LogFlowFunc(("Got new connection\n"));
     357
     358            int fdClient = accept(fdListen, NULL, NULL);
     359            if (fdClient == -1)
     360            {
     361                /* ignore this error... perhaps the client disconnected. */
     362                LogFlowFunc(("accept() failed [%d]\n", errno));
     363            }
     364            else
     365            {
     366                RTSOCKET hSock;
     367                vrc = RTSocketFromNative(&hSock, fdClient);
     368                if (RT_SUCCESS(vrc))
     369                {
     370                    if (AddClient(hPollSet, hSock) != 0)
     371                        RTSocketClose(hSock);
    379372                }
    380             }
    381 
    382             //
    383             // cleanup any dead clients (indicated by a zero in_flags)
    384             //
    385             for (i = pollCount - 1; i >= 1; --i) {
    386                 if (ipcPollList[i].in_flags == 0)
    387                     RemoveClient(i);
    388             }
    389 
    390             //
    391             // check for new connection
    392             //
    393             if (ipcPollList[0].out_flags & PR_POLL_READ) {
    394                 LOG(("got new connection\n"));
    395 
    396                 PRNetAddr clientAddr;
    397                 memset(&clientAddr, 0, sizeof(clientAddr));
    398                 PRFileDesc *clientFD;
    399 
    400                 // @todo : We need to handle errors from accept() especially something like
    401                 //          EMFILE, which happens when we run out of file descriptors.
    402                 //          and puts XPCOMIPCD in a poll/accept endless loop!
    403                 clientFD = PR_Accept(listenFD, &clientAddr, PR_INTERVAL_NO_WAIT);
    404                 if (clientFD == NULL) {
    405                     // ignore this error... perhaps the client disconnected.
    406                     LOG(("PR_Accept failed [%d]\n", PR_GetError()));
     373                else
     374                {
     375                    LogFlowFunc(("RTSocketFromNative(, %d) -> %Rrc\n", fdClient, vrc));
     376                    close(fdClient);
    407377                }
    408                 else {
    409                     // make socket non-blocking
    410                     PRSocketOptionData opt;
    411                     opt.option = PR_SockOpt_Nonblocking;
    412                     opt.value.non_blocking = PR_TRUE;
    413                     PR_SetSocketOption(clientFD, &opt);
    414 
    415                     if (AddClient(clientFD) != 0)
    416                         PR_Close(clientFD);
    417                 }
    418             }
    419         }
    420 
    421         //
    422         // shutdown if no clients
    423         //
    424         if (ipcClientCount == 0) {
    425             LOG(("shutting down\n"));
    426             break;
     378            }
     379        }
     380        else
     381        {
     382            uint32_t fNewFlags = ipcClientArray[idPoll].Process(fEvents);
     383            if (!fNewFlags)
     384            {
     385                /* Cleanup dead client. */
     386                RemoveClient(hPollSet, idPoll);
     387            }
     388            else if (ipcClientArray[idPoll].m_fPollEvts != fNewFlags)
     389            {
     390                /* Change flags. */
     391                vrc = RTPollSetEventsChange(hPollSet, idPoll, fNewFlags);
     392                AssertRC(vrc);
     393                ipcClientArray[idPoll].m_fPollEvts = fNewFlags;
     394            }
    427395        }
    428396    }
     
    434402IPC_PlatformSendMsg(ipcClient  *client, ipcMessage *msg)
    435403{
    436     LOG(("IPC_PlatformSendMsg\n"));
     404    LogFlowFunc(("IPC_PlatformSendMsg\n"));
    437405
    438406    //
     
    443411    //
    444412    // since our Process method may have already been called, we must ensure
    445     // that the PR_POLL_WRITE flag is set.
    446     //
    447     int clientIndex = client - ipcClientArray;
    448     ipcPollList[clientIndex].in_flags |= PR_POLL_WRITE;
     413    // that the RTPOLL_EVT_WRITE flag is set.
     414    //
     415    if (!(client->m_fPollEvts & RTPOLL_EVT_WRITE))
     416    {
     417        client->m_fPollEvts |= RTPOLL_EVT_WRITE;
     418        int vrc = RTPollSetEventsChange(g_hPollSet, client->m_idPoll, client->m_fPollEvts);
     419        AssertRC(vrc);
     420    }
    449421
    450422    return PR_SUCCESS;
     
    455427int main(int argc, char **argv)
    456428{
    457     PRFileDesc *listenFD = NULL;
    458     PRNetAddr addr;
    459 
    460429    /* Set up the runtime without loading the support driver. */
    461430    int vrc = RTR3InitExe(argc, &argv, 0);
     
    506475    umask(0077);
    507476
    508     IPC_InitLog("###");
    509 
    510     LOG(("daemon started...\n"));
     477    LogFlowFunc(("daemon started...\n"));
    511478
    512479    //XXX uncomment these lines to test slow starting daemon
    513480    //IPC_Sleep(2);
    514481
     482    struct sockaddr_un addr;
     483    memset(&addr, 0, sizeof(addr));
     484    addr.sun_family = AF_UNIX;
     485
    515486    // set socket address
    516     addr.local.family = PR_AF_LOCAL;
    517487    if (!pszSocketPath)
    518         IPC_GetDefaultSocketPath(addr.local.path, sizeof(addr.local.path));
     488        IPC_GetDefaultSocketPath(addr.sun_path, sizeof(addr.sun_path));
    519489    else
    520         PL_strncpyz(addr.local.path, pszSocketPath, sizeof(addr.local.path));
     490        PL_strncpyz(addr.sun_path, pszSocketPath, sizeof(addr.sun_path));
    521491
    522492#ifdef IPC_USE_FILE_LOCK
    523     Status status = InitDaemonDir(addr.local.path);
     493    Status status = InitDaemonDir(addr.sun_path);
    524494    if (status != EOk) {
    525495        if (status == ELockFileLock) {
    526             LOG(("Another daemon is already running, exiting.\n"));
     496            LogFlowFunc(("Another daemon is already running, exiting.\n"));
    527497            // send a signal to the blocked parent to indicate success
    528498            IPC_NotifyParent(uStartupPipeFd);
     
    530500        }
    531501        else {
    532             LOG(("InitDaemonDir failed (status=%d)\n", status));
     502            LogFlowFunc(("InitDaemonDir failed (status=%d)\n", status));
    533503            // don't notify the parent to cause it to fail in PR_Read() after
    534504            // we terminate
    535505            if (status != ELockFileOwner)
    536506                printf("Cannot create a lock file for '%s'.\n"
    537                         "Check permissions.\n", addr.local.path);
     507                        "Check permissions.\n", addr.sun_path);
    538508            return 0;
    539509        }
     
    541511#endif
    542512
    543     listenFD = PR_OpenTCPSocket(PR_AF_LOCAL);
    544     if (!listenFD) {
    545         LOG(("PR_OpenTCPSocket failed [%d]\n", PR_GetError()));
    546     }
    547     else if (PR_Bind(listenFD, &addr) != PR_SUCCESS) {
    548         LOG(("PR_Bind failed [%d]\n", PR_GetError()));
    549     }
    550     else {
    551         // Use large backlog, as otherwise local sockets can reject connection
    552         // attempts. Usually harmless, but causes an unnecessary start attempt
    553         // of IPCD (which will terminate straight away), and the next attempt
    554         // usually succeeds. But better avoid unnecessary activities.
    555         if (PR_Listen(listenFD, 128) != PR_SUCCESS) {
    556             LOG(("PR_Listen failed [%d]\n", PR_GetError()));
    557         }
    558         else {
    559 
    560             IPC_NotifyParent(uStartupPipeFd);
     513    int fdListen = socket(PF_UNIX, SOCK_STREAM, 0);
     514    if (fdListen == -1)
     515        LogFlowFunc(("socket failed [%d]\n", errno));
     516    else
     517    {
     518        if (bind(fdListen, (struct sockaddr *)&addr, sizeof(addr)) == 0)
     519        {
     520            // Use large backlog, as otherwise local sockets can reject connection
     521            // attempts. Usually harmless, but causes an unnecessary start attempt
     522            // of IPCD (which will terminate straight away), and the next attempt
     523            // usually succeeds. But better avoid unnecessary activities.
     524            if (listen(fdListen, 128) == 0)
     525            {
     526                IPC_NotifyParent(uStartupPipeFd);
    561527
    562528#if defined(VBOX) && !defined(XP_OS2)
    563             // Increase the file table size to 10240 or as high as possible.
    564             struct rlimit lim;
    565             if (getrlimit(RLIMIT_NOFILE, &lim) == 0)
    566             {
    567                 if (    lim.rlim_cur < 10240
    568                     &&  lim.rlim_cur < lim.rlim_max)
     529                // Increase the file table size to 10240 or as high as possible.
     530                struct rlimit lim;
     531                if (getrlimit(RLIMIT_NOFILE, &lim) == 0)
    569532                {
    570                     lim.rlim_cur = lim.rlim_max <= 10240 ? lim.rlim_max : 10240;
    571                     if (setrlimit(RLIMIT_NOFILE, &lim) == -1)
    572                         printf("WARNING: failed to increase file descriptor limit. (%d)\n", errno);
     533                    if (    lim.rlim_cur < 10240
     534                        &&  lim.rlim_cur < lim.rlim_max)
     535                    {
     536                        lim.rlim_cur = lim.rlim_max <= 10240 ? lim.rlim_max : 10240;
     537                        if (setrlimit(RLIMIT_NOFILE, &lim) == -1)
     538                            printf("WARNING: failed to increase file descriptor limit. (%d)\n", errno);
     539                    }
    573540                }
     541                else
     542                    printf("WARNING: failed to obtain per-process file-descriptor limit (%d).\n", errno);
     543#endif
     544
     545                RTSOCKET hSockListen;
     546                int vrc = RTSocketFromNative(&hSockListen, fdListen);
     547                if (RT_SUCCESS(vrc))
     548                {
     549                    fdListen = (int)RTSocketToNative(hSockListen);
     550
     551                    RTPOLLSET hPollSet = NIL_RTPOLLSET;
     552                    vrc = RTPollSetCreate(&hPollSet);
     553                    if (RT_SUCCESS(vrc))
     554                    {
     555                        g_hPollSet = hPollSet;
     556
     557                        vrc = RTPollSetAddSocket(hPollSet, hSockListen, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR, UINT32_MAX - 1);
     558                        if (RT_SUCCESS(vrc))
     559                            PollLoop(hPollSet, fdListen);
     560                        else
     561                            LogFlowFunc(("RTPollSetCreate() -> %Rrc\n", vrc));
     562                    }
     563                    else
     564                        LogFlowFunc(("RTPollSetCreate() -> %Rrc\n", vrc));
     565
     566                    vrc = RTPollSetDestroy(hPollSet);
     567                    AssertRC(vrc);
     568                }
     569                else
     570                    LogFlowFunc(("RTSocketFromNative() -> %Rrc\n", vrc));
     571
     572                vrc = RTSocketClose(hSockListen);
     573                AssertRC(vrc);
     574                fdListen = -1;
    574575            }
    575576            else
    576                 printf("WARNING: failed to obtain per-process file-descriptor limit (%d).\n", errno);
    577 #endif
    578 
    579             PollLoop(listenFD);
    580         }
     577                LogFlowFunc(("listen failed [%d]\n", errno));
     578        }
     579        else
     580            LogFlowFunc(("bind failed [%d]\n", errno));
     581
     582        LogFlowFunc(("closing socket\n"));
     583        if (fdListen != -1)
     584            close(fdListen);
    581585    }
    582586
     
    591595#endif
    592596
    593     if (listenFD) {
    594         LOG(("closing socket\n"));
    595         PR_Close(listenFD);
    596     }
    597 
    598597    return 0;
    599598}
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