Changeset 29785 in vbox for trunk/src/VBox/HostServices
- Timestamp:
- May 25, 2010 1:30:45 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 61989
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostServices/GuestControl/service.cpp
r29438 r29785 48 48 49 49 /** 50 * Structure for holding a buffered host command 50 * Structure for holding all clients with their 51 * generated host contexts. This is necessary for 52 * mainting the relationship between a client and its context IDs. 53 */ 54 struct ClientContexts 55 { 56 /** This client ID. */ 57 uint32_t mClientID; 58 /** The list of contexts a client is assigned to. */ 59 std::list< uint32_t > mContextList; 60 61 /** The normal contructor. */ 62 ClientContexts(uint32_t aClientID) 63 : mClientID(aClientID) {} 64 }; 65 /** The client list + iterator type */ 66 typedef std::list< ClientContexts > ClientContextsList; 67 typedef std::list< ClientContexts >::iterator ClientContextsListIter; 68 typedef std::list< ClientContexts >::const_iterator ClientContextsListIterConst; 69 70 /** 71 * Structure for holding a buffered host command. 51 72 */ 52 73 struct HostCmd 53 74 { 75 /** The context ID this command belongs to. Will be extracted 76 * from the HGCM parameters. */ 77 uint32_t mContextID; 54 78 /** Dynamic structure for holding the HGCM parms */ 55 VBOXGUESTCTRPARAMBUFFER parmBuf; 79 VBOXGUESTCTRPARAMBUFFER mParmBuf; 80 81 /** The standard contructor. */ 82 HostCmd() : mContextID(0) {} 56 83 }; 57 84 /** The host cmd list + iterator type */ … … 61 88 62 89 /** 63 * Structure for holding an uncompleted guest call 90 * Structure for holding an uncompleted guest call. 64 91 */ 65 92 struct GuestCall … … 74 101 uint32_t mNumParms; 75 102 76 /** The standard con structor*/103 /** The standard contructor. */ 77 104 GuestCall() : mClientID(0), mHandle(0), mParms(NULL), mNumParms(0) {} 78 /** The normal contructor */105 /** The normal contructor. */ 79 106 GuestCall(uint32_t aClientID, VBOXHGCMCALLHANDLE aHandle, 80 107 VBOXHGCMSVCPARM aParms[], uint32_t cParms) … … 92 119 { 93 120 private: 94 /** Type definition for use in callback functions */121 /** Type definition for use in callback functions. */ 95 122 typedef Service SELF; 96 123 /** HGCM helper functions. */ 97 124 PVBOXHGCMSVCHELPERS mpHelpers; 98 /** Callback function supplied by the host for notification of updates 99 * to properties */ 125 /* 126 * Callback function supplied by the host for notification of updates 127 * to properties. 128 */ 100 129 PFNHGCMSVCEXT mpfnHostCallback; 101 /** User data pointer to be supplied to the host callback function */130 /** User data pointer to be supplied to the host callback function. */ 102 131 void *mpvHostData; 103 /** The deferred calls list */132 /** The deferred calls list. */ 104 133 CallList mClientList; 105 /** The host command list */134 /** The host command list. */ 106 135 HostCmdList mHostCmds; 136 /** Client contexts list. */ 137 ClientContextsList mClientContextsList; 107 138 108 139 public: … … 368 399 { 369 400 LogFlowFunc(("Client (%ld) disconnected\n", u32ClientID)); 401 370 402 /* 371 403 * Throw out all stale clients. 372 404 */ 373 CallListIter it = mClientList.begin(); 374 while (it != mClientList.end()) 405 int rc = VINF_SUCCESS; 406 407 ClientContextsListIter it = mClientContextsList.begin(); 408 while ( it != mClientContextsList.end() 409 && RT_SUCCESS(rc)) 375 410 { 376 411 if (it->mClientID == u32ClientID) 377 it = mClientList.erase(it); 412 { 413 std::list< uint32_t >::iterator itContext = it->mContextList.begin(); 414 while ( itContext != it->mContextList.end() 415 && RT_SUCCESS(rc)) 416 { 417 LogFlowFunc(("Notifying host context %u of disconnect ...\n", (*itContext))); 418 419 /* 420 * Notify the host that clients with u32ClientID are no longer 421 * around and need to be cleaned up (canceling waits etc). 422 */ 423 if (mpfnHostCallback) 424 { 425 CALLBACKDATACLIENTDISCONNECTED data; 426 data.hdr.u32Magic = CALLBACKDATAMAGICCLIENTDISCONNECTED; 427 data.hdr.u32ContextID = (*itContext); 428 rc = mpfnHostCallback(mpvHostData, GUEST_DISCONNECTED, (void *)(&data), sizeof(data)); 429 if (RT_FAILURE(rc)) 430 LogFlowFunc(("Notification of host context %u failed with %Rrc\n", rc)); 431 } 432 itContext++; 433 } 434 it = mClientContextsList.erase(it); 435 } 378 436 else 379 437 it++; 380 438 } 381 return VINF_SUCCESS;439 return rc; 382 440 } 383 441 … … 388 446 389 447 /* Sufficient parameter space? */ 390 if (pCmd-> parmBuf.uParmCount > cParms)391 { 392 paParms[0].setUInt32(pCmd-> parmBuf.uMsg); /* Message ID */393 paParms[1].setUInt32(pCmd-> parmBuf.uParmCount); /* Required parameters for message */448 if (pCmd->mParmBuf.uParmCount > cParms) 449 { 450 paParms[0].setUInt32(pCmd->mParmBuf.uMsg); /* Message ID */ 451 paParms[1].setUInt32(pCmd->mParmBuf.uParmCount); /* Required parameters for message */ 394 452 395 453 /* … … 402 460 else 403 461 { 404 rc = paramBufferAssign(&pCmd-> parmBuf, cParms, paParms);462 rc = paramBufferAssign(&pCmd->mParmBuf, cParms, paParms); 405 463 } 406 464 return rc; … … 415 473 { 416 474 int rc = VINF_SUCCESS; 475 476 /* 477 * Lookup client in our list so that we can assign the context ID of 478 * a command to that client. 479 */ 480 std::list< ClientContexts >::reverse_iterator it = mClientContextsList.rbegin(); 481 while (it != mClientContextsList.rend()) 482 { 483 if (it->mClientID == u32ClientID) 484 break; 485 it++; 486 } 487 488 /* Not found? Add client to list. */ 489 if (it == mClientContextsList.rend()) 490 { 491 mClientContextsList.push_back(ClientContexts(u32ClientID)); 492 it = mClientContextsList.rbegin(); 493 } 494 Assert(it != mClientContextsList.rend()); 417 495 418 496 /* … … 435 513 if (RT_SUCCESS(rc)) 436 514 { 437 /* Only if the guest really got and understood the message 438 * remove it from the list. */ 439 paramBufferFree(&curCmd.parmBuf); 515 /* Remember which client processes which context (for 516 * later reference & cleanup). */ 517 Assert(curCmd.mContextID > 0); 518 it->mContextList.push_back(curCmd.mContextID); 519 520 /* Only if the guest really got and understood the message remove it from the list. */ 521 paramBufferFree(&curCmd.mParmBuf); 440 522 mHostCmds.pop_front(); 441 523 } … … 444 526 } 445 527 528 /* 529 * Client asks itself (in another thread) to cancel all pending waits which are blocking the client 530 * from shutting down / doing something else. 531 */ 446 532 int Service::cancelPendingWaits(uint32_t u32ClientID) 447 533 { … … 454 540 if (it->mNumParms >= 2) 455 541 { 456 it->mParms[0].setUInt32(GETHOSTMSG_EXEC_HOST_CANCEL_WAIT); /* Message ID */457 it->mParms[1].setUInt32(0); /* Required parameters for message */542 it->mParms[0].setUInt32(GETHOSTMSG_EXEC_HOST_CANCEL_WAIT); /* Message ID. */ 543 it->mParms[1].setUInt32(0); /* Required parameters for message. */ 458 544 } 459 545 if (mpHelpers) … … 475 561 && cParms == 5) 476 562 { 477 HOSTEXECCALLBACKDATAdata;478 data.hdr.u32Magic = HOSTEXECCALLBACKDATAMAGIC;563 CALLBACKDATAEXECSTATUS data; 564 data.hdr.u32Magic = CALLBACKDATAMAGICEXECSTATUS; 479 565 paParms[0].getUInt32(&data.hdr.u32ContextID); 480 566 … … 491 577 && cParms == 5) 492 578 { 493 HOSTEXECOUTCALLBACKDATAdata;494 data.hdr.u32Magic = HOSTEXECOUTCALLBACKDATAMAGIC;579 CALLBACKDATAEXECOUT data; 580 data.hdr.u32Magic = CALLBACKDATAMAGICEXECOUT; 495 581 paParms[0].getUInt32(&data.hdr.u32ContextID); 496 582 … … 515 601 516 602 HostCmd newCmd; 603 rc = paramBufferAllocate(&newCmd.mParmBuf, eFunction, cParms, paParms); 604 if ( RT_SUCCESS(rc) 605 && newCmd.mParmBuf.uParmCount > 0) 606 { 607 /* 608 * Assume that the context ID *always* is the first parameter, 609 * assign the context ID to the command. 610 */ 611 newCmd.mParmBuf.pParms[0].getUInt32(&newCmd.mContextID); 612 Assert(newCmd.mContextID > 0); 613 } 614 517 615 bool fProcessed = false; 518 rc = paramBufferAllocate(&newCmd.parmBuf, eFunction, cParms, paParms);519 616 if (RT_SUCCESS(rc)) 520 617 { … … 539 636 else /* If command was understood by the client, free and remove from host commands list. */ 540 637 { 541 paramBufferFree(&newCmd. parmBuf);638 paramBufferFree(&newCmd.mParmBuf); 542 639 fProcessed = true; 543 640 } … … 668 765 HostCmdListIter it; 669 766 for (it = mHostCmds.begin(); it != mHostCmds.end(); it++) 670 paramBufferFree(&it-> parmBuf);767 paramBufferFree(&it->mParmBuf); 671 768 mHostCmds.clear(); 672 769
Note:
See TracChangeset
for help on using the changeset viewer.