Changeset 26375 in vbox for trunk/src/VBox
- Timestamp:
- Feb 9, 2010 2:24:56 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 57468
- Location:
- trunk/src/VBox/Main/webservice
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/webservice/vboxweb.cpp
r26089 r26375 32 32 #include <VBox/version.h> 33 33 34 #include <iprt/ cpp/lock.h>34 #include <iprt/thread.h> 35 35 #include <iprt/rand.h> 36 36 #include <iprt/initterm.h> … … 114 114 ****************************************************************************/ 115 115 116 RTLockMtx g_mutexAuthLib; 116 // this mutex protects the auth lib and authentication 117 util::RWLockHandle *g_pAuthLibLockHandle; 117 118 118 119 // this mutex protects all of the below 119 RTLockMtx g_mutexSessions;120 util::RWLockHandle *g_pSessionsLockHandle; 120 121 121 122 SessionsMap g_mapSessions; … … 247 248 } 248 249 250 /** 251 * Called from main(). This implements the loop that takes SOAP calls 252 * from HTTP and serves them, calling the COM method implementations 253 * in the generated methodmaps.cpp code. 254 */ 255 void beginProcessing() 256 { 257 // set up gSOAP 258 struct soap soap; 259 soap_init(&soap); 260 261 soap.bind_flags |= SO_REUSEADDR; 262 // avoid EADDRINUSE on bind() 263 264 int m, s; // master and slave sockets 265 m = soap_bind(&soap, 266 g_pcszBindToHost, // host: current machine 267 g_uBindToPort, // port 268 g_uBacklog); // backlog = max queue size for requests 269 if (m < 0) 270 WebLogSoapError(&soap); 271 else 272 { 273 WebLog("Socket connection successful: host = %s, port = %u, master socket = %d\n", 274 (g_pcszBindToHost) ? g_pcszBindToHost : "default (localhost)", 275 g_uBindToPort, 276 m); 277 278 for (uint64_t i = 1; 279 ; 280 i++) 281 { 282 // call gSOAP to handle incoming SOAP connection 283 s = soap_accept(&soap); 284 if (s < 0) 285 { 286 WebLogSoapError(&soap); 287 break; 288 } 289 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 309 310 // we have to process main event queue 311 int vrc = com::EventQueue::getMainEventQueue()->processEventQueue(0); 312 } 313 } 314 soap_done(&soap); // close master socket and detach environment 315 } 249 316 250 317 /** … … 390 457 } 391 458 459 // create the global mutexes 460 g_pAuthLibLockHandle = new util::RWLockHandle(util::LOCKCLASS_OBJECTSTATE); 461 g_pSessionsLockHandle = new util::RWLockHandle(util::LOCKCLASS_OBJECTSTATE); 462 392 463 if (g_iWatchdogTimeoutSecs > 0) 393 464 { … … 407 478 } 408 479 409 // set up gSOAP 410 struct soap soap; 411 soap_init(&soap); 412 413 soap.bind_flags |= SO_REUSEADDR; 414 // avoid EADDRINUSE on bind() 415 416 int m, s; // master and slave sockets 417 m = soap_bind(&soap, 418 g_pcszBindToHost, // host: current machine 419 g_uBindToPort, // port 420 g_uBacklog); // backlog = max queue size for requests 421 if (m < 0) 422 WebLogSoapError(&soap); 423 else 424 { 425 WebLog("Socket connection successful: host = %s, port = %u, master socket = %d\n", 426 (g_pcszBindToHost) ? g_pcszBindToHost : "default (localhost)", 427 g_uBindToPort, 428 m); 429 430 for (uint64_t i = 1; 431 ; 432 i++) 433 { 434 // call gSOAP to handle incoming SOAP connection 435 s = soap_accept(&soap); 436 if (s < 0) 437 { 438 WebLogSoapError(&soap); 439 break; 440 } 441 442 WebLog("%llu: accepted connection from IP=%lu.%lu.%lu.%lu socket=%d... ", 443 i, 444 (soap.ip>>24)&0xFF, 445 (soap.ip>>16)&0xFF, 446 (soap.ip>>8)&0xFF, 447 soap.ip&0xFF, 448 s); 449 450 // enclose the entire RPC call in the sessions lock 451 // so that the watchdog cannot destroy COM objects 452 // while the RPC is ongoing 453 RTLock lock(g_mutexSessions); 454 // now process the RPC request (this goes into the 455 // generated code in methodmaps.cpp with all the COM calls) 456 if (soap_serve(&soap) != SOAP_OK) 457 { 458 WebLogSoapError(&soap); 459 } 460 lock.release(); 461 462 WebLog("Request served\n"); 463 464 soap_destroy(&soap); // clean up class instances 465 soap_end(&soap); // clean up everything and close socket 466 467 // we have to process main event queue 468 int vrc = com::EventQueue::getMainEventQueue()->processEventQueue(0); 469 } 470 } 471 soap_done(&soap); // close master socket and detach environment 480 beginProcessing(); 472 481 473 482 com::Shutdown(); … … 499 508 time(&tNow); 500 509 501 RTLock lock(g_mutexSessions); 510 // lock the sessions while we're iterating; this blocks 511 // out the COM code from messing with it 512 util::AutoWriteLock lock(g_pSessionsLockHandle COMMA_LOCKVAL_SRC_POS); 502 513 WEBDEBUG(("Watchdog: checking %d sessions\n", g_mapSessions.size())); 503 514 504 SessionsMap::iterator 505 it = g_mapSessions.begin(), 506 itEnd = g_mapSessions.end(); 515 SessionsMap::iterator it = g_mapSessions.begin(), 516 itEnd = g_mapSessions.end(); 507 517 while (it != itEnd) 508 518 { … … 520 530 ++it; 521 531 } 522 lock.release();523 532 } 524 533 … … 617 626 std::string ConvertComString(const com::Guid &uuid) 618 627 { 619 com::Bstr bstr(uuid); 620 com::Utf8Str ustr(bstr); 628 com::Utf8Str ustr(uuid.toString()); 621 629 const char *pcsz; 622 630 if ((pcsz = ustr.raw())) … … 739 747 * Constructor for the session object. 740 748 * 741 * Preconditions: Caller must have locked g_ mutexSessions.749 * Preconditions: Caller must have locked g_pSessionsLockHandle in write mode. 742 750 * 743 751 * @param username … … 753 761 754 762 // register this session globally 763 Assert(g_pSessionsLockHandle->isWriteLockOnCurrentThread()); 755 764 g_mapSessions[_uSessionID] = this; 756 765 } … … 759 768 * Destructor. Cleans up and destroys all contained managed object references on the way. 760 769 * 761 * Preconditions: Caller must have locked g_ mutexSessions.770 * Preconditions: Caller must have locked g_pSessionsLockHandle in write mode. 762 771 */ 763 772 WebServiceSession::~WebServiceSession() … … 765 774 // delete us from global map first so we can't be found 766 775 // any more while we're cleaning up 776 Assert(g_pSessionsLockHandle->isWriteLockOnCurrentThread()); 767 777 g_mapSessions.erase(_uSessionID); 768 778 … … 778 788 // } 779 789 780 ManagedObjectsMapById::iterator 781 it, 782 end = _pp->_mapManagedObjectsById.end(); 790 ManagedObjectsMapById::iterator it, 791 end = _pp->_mapManagedObjectsById.end(); 783 792 for (it = _pp->_mapManagedObjectsById.begin(); 784 793 it != end; … … 804 813 int rc = VERR_WEB_NOT_AUTHENTICATED; 805 814 806 RTLock lock(g_mutexAuthLib);815 util::AutoReadLock lock(g_pAuthLibLockHandle COMMA_LOCKVAL_SRC_POS); 807 816 808 817 static bool fAuthLibLoaded = false; … … 875 884 } 876 885 886 lock.release(); 887 877 888 if (!rc) 878 889 { … … 912 923 * our private hash table, we must search for one too. 913 924 * 914 * Preconditions: Caller must have locked g_mutexSessions.925 * Preconditions: Caller must have locked g_pSessionsLockHandle in read mode. 915 926 * 916 927 * @param pcu pointer to a COM object. … … 919 930 ManagedObjectRef* WebServiceSession::findRefFromPtr(const ComPtr<IUnknown> &pcu) 920 931 { 932 // Assert(g_pSessionsLockHandle->isReadLockOnCurrentThread()); // @todo 933 921 934 IUnknown *p = pcu; 922 935 uintptr_t ulp = (uintptr_t)p; … … 940 953 * object IDs and then looking up the session object for that session ID. 941 954 * 942 * Preconditions: Caller must have locked g_ mutexSessions.955 * Preconditions: Caller must have locked g_pSessionsLockHandle in read mode. 943 956 * 944 957 * @param id Managed object reference (with combined session and object IDs). … … 947 960 WebServiceSession* WebServiceSession::findSessionFromRef(const WSDLT_ID &id) 948 961 { 962 // Assert(g_pSessionsLockHandle->isReadLockOnCurrentThread()); // @todo 963 949 964 WebServiceSession *pSession = NULL; 950 965 uint64_t sessid; … … 1010 1025 /** 1011 1026 * Constructor, which assigns a unique ID to this managed object 1012 * reference and stores it two global hash s:1027 * reference and stores it two global hashes: 1013 1028 * 1014 1029 * a) G_mapManagedObjectsById, which maps ManagedObjectID's to … … 1294 1309 1295 1310 do { 1311 // WebServiceSession constructor tinkers with global MOR map and requires a write lock 1312 util::AutoWriteLock lock(g_pSessionsLockHandle COMMA_LOCKVAL_SRC_POS); 1313 1296 1314 // create new session; the constructor stores the new session 1297 1315 // in the global map automatically -
trunk/src/VBox/Main/webservice/vboxweb.h
r22708 r26375 3 3 * header file for "real" web server code. 4 4 * 5 * Copyright (C) 2006-20 07Sun Microsystems, Inc.5 * Copyright (C) 2006-2010 Sun Microsystems, Inc. 6 6 * 7 7 * This file is part of VirtualBox Open Source Edition (OSE), as … … 33 33 #include <VBox/com/VirtualBox.h> 34 34 #include <VBox/com/Guid.h> 35 #include <VBox/com/AutoLock.h> 35 36 36 37 #include <VBox/err.h> … … 39 40 40 41 #include <string> 41 42 42 43 43 /**************************************************************************** … … 51 51 52 52 extern PRTSTREAM g_pstrLog; 53 54 extern util::RWLockHandle *g_pAuthLibLockHandle; 55 56 extern util::RWLockHandle *g_pSessionsLockHandle; 53 57 54 58 /**************************************************************************** … … 224 228 bool fNullAllowed) 225 229 { 230 // we're only reading the MOR maps, not modifying them, so a readlock is good enough 231 // (allow concurrency, this code gets called from everywhere in methodmaps.cpp) 232 util::AutoReadLock lock(g_pSessionsLockHandle COMMA_LOCKVAL_SRC_POS); 233 226 234 int rc; 227 235 ManagedObjectRef *pRef; … … 270 278 } 271 279 280 // we might be modifying the MOR maps below, so request write lock now 281 util::AutoWriteLock lock(g_pSessionsLockHandle COMMA_LOCKVAL_SRC_POS); 272 282 WebServiceSession *pSession; 273 283 if ((pSession = WebServiceSession::findSessionFromRef(idParent)))
Note:
See TracChangeset
for help on using the changeset viewer.