Changeset 26393 in vbox
- Timestamp:
- Feb 9, 2010 5:50:17 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/webservice/vboxweb.cpp
r26375 r26393 40 40 #include <iprt/string.h> 41 41 #include <iprt/ldr.h> 42 #include <iprt/semaphore.h> 42 43 43 44 // workaround for compile problems on gcc 4.1 … … 51 52 // standard headers 52 53 #include <map> 54 #include <list> 53 55 54 56 #ifdef __GNUC__ … … 248 250 } 249 251 252 int fntSoapQueue(RTTHREAD pThread, void *pvThread); 253 254 class SoapQ; 255 256 struct SoapThread 257 { 258 size_t u; 259 SoapQ *pQ; 260 struct soap *soap; 261 RTTHREAD pThread; 262 }; 263 264 class SoapQ 265 { 266 public: 267 SoapQ(size_t cThreads, const struct soap *pSoap) 268 : m_mutex(util::LOCKCLASS_OBJECTSTATE), 269 m_cIdleThreads(0) 270 { 271 RTSemEventCreate(&m_event); 272 273 // create cThreads threads 274 for (size_t u = 0; u < cThreads; ++u) 275 { 276 SoapThread *pst = new SoapThread(); 277 pst->u = u + 1; 278 pst->pQ = this; 279 pst->soap = soap_copy(pSoap); 280 RTThreadCreate(&pst->pThread, 281 fntSoapQueue, 282 pst, // pvUser 283 0, // cbStack, 284 RTTHREADTYPE_MAIN_HEAVY_WORKER, 285 0, 286 "SoapQWorker"); 287 m_llAllThreads.push_back(pst); 288 ++m_cIdleThreads; 289 } 290 } 291 292 ~SoapQ() 293 { 294 RTSemEventDestroy(m_event); 295 } 296 297 util::WriteLockHandle m_mutex; 298 RTSEMEVENT m_event; 299 300 std::list<SoapThread*> m_llAllThreads; 301 size_t m_cIdleThreads; 302 303 std::list<int> m_llSocketsQ; // this contains the actual jobs to do, 304 // represented by the socket from soap_accept() 305 }; 306 307 int fntSoapQueue(RTTHREAD pThread, void *pvThread) 308 { 309 SoapThread *pst = (SoapThread*)pvThread; 310 311 WebLog("Started thread %d\n", pst->u); 312 313 while (1) 314 { 315 // wait for something to happen 316 RTSemEventWait(pst->pQ->m_event, RT_INDEFINITE_WAIT); 317 318 util::AutoWriteLock qlock(pst->pQ->m_mutex COMMA_LOCKVAL_SRC_POS); 319 if (pst->pQ->m_llSocketsQ.size()) 320 { 321 pst->soap->socket = pst->pQ->m_llSocketsQ.front(); 322 pst->pQ->m_llSocketsQ.pop_front(); 323 --pst->pQ->m_cIdleThreads; 324 qlock.release(); 325 326 WebLog("Thread %d is handling connection from IP=%lu.%lu.%lu.%lu socket=%d (%d threads idle)", 327 pst->u, 328 (pst->soap->ip>>24)&0xFF, 329 (pst->soap->ip>>16)&0xFF, 330 (pst->soap->ip>>8)&0xFF, 331 pst->soap->ip&0xFF, 332 pst->soap->socket, 333 pst->pQ->m_cIdleThreads); 334 335 // process the request; this goes into the COM code in methodmaps.cpp 336 soap_serve(pst->soap); 337 338 soap_destroy(pst->soap); // clean up class instances 339 soap_end(pst->soap); // clean up everything and close socket 340 341 qlock.acquire(); 342 ++pst->pQ->m_cIdleThreads; 343 } 344 } 345 346 return 0; 347 } 348 250 349 /** 251 350 * Called from main(). This implements the loop that takes SOAP calls … … 276 375 m); 277 376 377 // initialize thread queue, mutex and eventsem, create 10 threads 378 SoapQ soapq(10, &soap); 379 278 380 for (uint64_t i = 1; 279 381 ; … … 288 390 } 289 391 290 WebLog("%llu: accepted connection from IP=%lu.%lu.%lu.%lu socket=%d... ", 291 i, 292 (soap.ip>>24)&0xFF, 293 (soap.ip>>16)&0xFF, 294 (soap.ip>>8)&0xFF, 295 soap.ip&0xFF, 296 s); 297 298 // now process the RPC request (this goes into the 299 // generated code in methodmaps.cpp with all the COM calls) 300 if (soap_serve(&soap) != SOAP_OK) 301 { 302 WebLogSoapError(&soap); 303 } 304 305 WebLog("Request served\n"); 306 307 soap_destroy(&soap); // clean up class instances 308 soap_end(&soap); // clean up everything and close socket 392 // enqueue the socket of this connection and post eventsem so 393 // that one of our threads can pick it up 394 util::AutoWriteLock qlock(soapq.m_mutex COMMA_LOCKVAL_SRC_POS); 395 soapq.m_llSocketsQ.push_back(s); 396 WebLog("Request %llu on socket %d queued for processing\n", i, s); 397 RTSemEventSignal(soapq.m_event); 398 qlock.release(); 309 399 310 400 // we have to process main event queue … … 332 422 RTR3Init(); 333 423 334 RTStrmPrintf(g_pStdErr, VBOX_PRODUCT " Webservice Version " VBOX_VERSION_STRING "\n"424 RTStrmPrintf(g_pStdErr, VBOX_PRODUCT " web service version " VBOX_VERSION_STRING "\n" 335 425 "(C) 2005-" VBOX_C_YEAR " " VBOX_VENDOR "\n" 336 426 "All rights reserved.\n"); … … 1045 1135 * does perform that check. 1046 1136 * 1047 * Preconditions: Caller must have locked g_mutexSessions.1137 * Preconditions: Caller must have locked g_pSessionsLockHandle in write mode. 1048 1138 * 1049 1139 * @param pObj … … 1059 1149 _ulp = (uintptr_t)(IUnknown*)pcUnknown; 1060 1150 1151 Assert(g_pSessionsLockHandle->isWriteLockOnCurrentThread()); 1061 1152 _id = ++g_iMaxManagedObjectID; 1062 1153 // and count globally … … 1079 1170 * managed objects. 1080 1171 * 1081 * Preconditions: Caller must have locked g_ mutexSessions.1172 * Preconditions: Caller must have locked g_pSessionsLockHandle in write mode. 1082 1173 */ 1083 1174 ManagedObjectRef::~ManagedObjectRef() 1084 1175 { 1176 Assert(g_pSessionsLockHandle->isWriteLockOnCurrentThread()); 1085 1177 ULONG64 cTotal = --g_cManagedObjects; 1086 1178
Note:
See TracChangeset
for help on using the changeset viewer.