VirtualBox

Changeset 26398 in vbox


Ignore:
Timestamp:
Feb 9, 2010 7:12:50 PM (15 years ago)
Author:
vboxsync
Message:

Web service: gloss

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/webservice/vboxweb.cpp

    r26397 r26398  
    256256}
    257257
    258 int fntSoapQueue(RTTHREAD pThread, void *pvThread);
     258/****************************************************************************
     259 *
     260 * SoapQ, SoapThread (multithreading)
     261 *
     262 ****************************************************************************/
    259263
    260264class SoapQ;
    261265
    262 struct SoapThread
    263 {
    264     size_t      u;
    265     SoapQ       *pQ;
    266     struct soap *soap;
    267     RTTHREAD    pThread;
     266class SoapThread
     267{
     268public:
     269    /**
     270     * Constructor. Creates the new thread and makes it call process() for processing the queue.
     271     * @param u Thread number. (So we can count from 1 and be readable.)
     272     * @param q SoapQ instance which has the queue to process.
     273     * @param soap struct soap instance from main() which we copy here.
     274     */
     275    SoapThread(size_t u,
     276               SoapQ &q,
     277               const struct soap *soap)
     278        : m_u(u),
     279          m_pQ(&q)
     280    {
     281        // make a copy of the soap struct for the new thread
     282        m_soap = soap_copy(soap);
     283
     284        if (!RT_SUCCESS(RTThreadCreate(&m_pThread,
     285                                       fntWrapper,
     286                                       this,             // pvUser
     287                                       0,               // cbStack,
     288                                       RTTHREADTYPE_MAIN_HEAVY_WORKER,
     289                                       0,
     290                                       "SoapQWorker")))
     291        {
     292            RTStrmPrintf(g_pStdErr, "[!] Cannot start worker thread %d\n", u);
     293            exit(1);
     294        }
     295    }
     296
     297    void process();
     298
     299    static int fntWrapper(RTTHREAD pThread, void *pvThread)
     300    {
     301        SoapThread *pst = (SoapThread*)pvThread;
     302        pst->process();     // this never returns really
     303        return 0;
     304    }
     305
     306private:
     307    size_t      m_u;            // thread number
     308    SoapQ       *m_pQ;
     309    struct soap *m_soap;
     310    RTTHREAD    m_pThread;
    268311};
    269312
     313/**
     314 * SOAP queue encapsulation. add() adds an item to the queue,
     315 * get() fetches one.
     316 */
    270317class SoapQ
    271318{
     
    280327        for (size_t u = 0; u < cThreads; ++u)
    281328        {
    282             SoapThread *pst = new SoapThread();
    283             pst->u = u + 1;
    284             pst->pQ = this;
    285             pst->soap = soap_copy(pSoap);
    286             if (!RT_SUCCESS(RTThreadCreate(&pst->pThread,
    287                                            fntSoapQueue,
    288                                            pst,             // pvUser
    289                                            0,               // cbStack,
    290                                            RTTHREADTYPE_MAIN_HEAVY_WORKER,
    291                                            0,
    292                                            "SoapQWorker")))
    293             {
    294                 RTStrmPrintf(g_pStdErr, "[!] Cannot start worker thread %d\n", pst->u);
    295                 exit(1);
    296             }
    297 
     329            SoapThread *pst = new SoapThread(u + 1,
     330                                             *this,
     331                                             pSoap);
    298332            m_llAllThreads.push_back(pst);
    299333            ++m_cIdleThreads;
     
    308342    /**
    309343     * Adds the given socket to the SOAP queue and posts the
    310      * member event sem to wake up the workers.
     344     * member event sem to wake up the workers. Called on the main thread
     345     * whenever a socket has work to do.
    311346     * @param s Socket from soap_accept() which has work to do.
    312347     */
     
    331366     * the SOAP socket which has work to do. This reduces m_cIdleThreads
    332367     * by one, and the caller MUST call done() when it's done processing.
     368     * Called from the worker threads.
    333369     * @return
    334370     */
    335     int get()
     371    int get(size_t &cIdleThreads)
    336372    {
    337373        while (1)
     
    345381                int socket = m_llSocketsQ.front();
    346382                m_llSocketsQ.pop_front();
    347                 --m_cIdleThreads;
     383                cIdleThreads = --m_cIdleThreads;
    348384
    349385                // reset the multi event only if the queue is now empty; otherwise
     
    363399
    364400    /**
    365      * To be called by a thread after fetching an item from the
     401     * To be called by a worker thread after fetching an item from the
    366402     * queue via get() and having finished its lengthy processing.
    367403     */
     
    373409
    374410    util::WriteLockHandle   m_mutex;
    375     RTSEMEVENTMULTI         m_event;
    376 
    377     std::list<SoapThread*>  m_llAllThreads;
    378     size_t                  m_cIdleThreads;
    379 
    380     std::list<int>          m_llSocketsQ;       // this contains the actual jobs to do,
    381                                                 // represented by the socket from soap_accept()
     411    RTSEMEVENTMULTI         m_event;            // posted by add(), blocked on by get()
     412
     413    std::list<SoapThread*>  m_llAllThreads;     // all the threads created by the constructor
     414    size_t                  m_cIdleThreads;     // threads which are currently idle (statistics)
     415
     416    // A std::list abused as a queue; this contains the actual jobs to do,
     417    // each int being a socket from soap_accept()
     418    std::list<int>          m_llSocketsQ;
    382419};
    383420
     
    387424 * up a socket from the queue therein, which has been put there by
    388425 * beginProcessing().
    389  *
    390  * @param pThread
    391  * @param pvThread
    392  * @return
    393  */
    394 int fntSoapQueue(RTTHREAD pThread, void *pvThread)
    395 {
    396     SoapThread *pst = (SoapThread*)pvThread;
    397 
    398     WebLog("Started thread %d\n", pst->u);
     426 */
     427void SoapThread::process()
     428{
     429    WebLog("Started thread %d\n", m_u);
    399430
    400431    while (1)
    401432    {
    402433        // wait for a socket to arrive on the queue
    403         pst->soap->socket = pst->pQ->get();
     434        size_t cIdleThreads;
     435        m_soap->socket = m_pQ->get(cIdleThreads);
    404436
    405437        WebLog("T%d handles connection from IP=%lu.%lu.%lu.%lu socket=%d (%d threads idle)\n",
    406                 pst->u,
    407                 (pst->soap->ip>>24)&0xFF,
    408                 (pst->soap->ip>>16)&0xFF,
    409                 (pst->soap->ip>>8)&0xFF,
    410                 pst->soap->ip&0xFF,
    411                 pst->soap->socket,
    412                 pst->pQ->m_cIdleThreads);
     438                m_u,
     439                (m_soap->ip>>24)&0xFF,
     440                (m_soap->ip>>16)&0xFF,
     441                (m_soap->ip>>8)&0xFF,
     442                m_soap->ip&0xFF,
     443                m_soap->socket,
     444                cIdleThreads);
    413445
    414446        // process the request; this goes into the COM code in methodmaps.cpp
    415         soap_serve(pst->soap);
    416 
    417         soap_destroy(pst->soap); // clean up class instances
    418         soap_end(pst->soap); // clean up everything and close socket
     447        soap_serve(m_soap);
     448
     449        soap_destroy(m_soap); // clean up class instances
     450        soap_end(m_soap); // clean up everything and close socket
    419451
    420452        // tell the queue we're idle again
    421         pst->pQ->done();
    422     }
    423 
    424     return 0;
    425 }
     453        m_pQ->done();
     454    }
     455}
     456
     457/****************************************************************************
     458 *
     459 * Main
     460 *
     461 ****************************************************************************/
    426462
    427463/**
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