Changeset 91625 in vbox
- Timestamp:
- Oct 7, 2021 9:17:12 PM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/GuestHost/SharedClipboard/clipboard-common.cpp
r87687 r91625 232 232 AssertMsgFailed(("Unable to register a new event ID for event source %RU16\n", pSource->uID)); 233 233 234 RTSemEventMultiDestroy(pEvent->hEvtMulSem); 235 pEvent->hEvtMulSem = NIL_RTSEMEVENTMULTI; 234 236 RTMemFree(pEvent); 235 237 return NIL_SHCLEVENTID; … … 324 326 * @returns VBox status code. 325 327 * @param pSource Event source to unregister event for. 326 * @param uID Event ID to unregister. 328 * @param uID Event ID to unregister. 329 * 330 * @todo r=bird: The caller must enter crit sect protecting the event source 331 * here, must it? See explanation in ShClEventWait. 327 332 */ 328 333 int ShClEventUnregister(PSHCLEVENTSOURCE pSource, SHCLEVENTID uID) … … 364 369 * @param ppPayload Where to store the (allocated) event payload on success. Needs to be free'd with 365 370 * SharedClipboardPayloadFree(). Optional. 366 */ 367 int ShClEventWait(PSHCLEVENTSOURCE pSource, SHCLEVENTID uID, RTMSINTERVAL uTimeoutMs, 368 PSHCLEVENTPAYLOAD* ppPayload) 371 * 372 * @todo r=bird: Locking protocol is totally buggered here, or at least not 373 * explained in any way whatsoever. We cannot really do shclEventGet 374 * and shclEventPayloadDetachInternal w/o holding the critical section 375 * protecting that list, otherwise wtf is the point of the locking. 376 * 377 * More to the point, ShClEventSignal is called on the HGCM service 378 * thread and would be racing the host clipboard worker thread/whomever 379 * sent the request and is making this call closely followed by 380 * ShClEventRelease and ShClEventUnregister. The waiting here might be 381 * safe if there can only ever be one single thread making these kind 382 * of requests, but the unregistering is _not_ safe w/o holding the 383 * lock and that isn't explained anywhere that I can see. 384 */ 385 int ShClEventWait(PSHCLEVENTSOURCE pSource, SHCLEVENTID uID, RTMSINTERVAL uTimeoutMs, PSHCLEVENTPAYLOAD *ppPayload) 369 386 { 370 387 AssertPtrReturn(pSource, VERR_INVALID_POINTER); 371 /** ppPayload is optional. */ 372 388 AssertPtrNullReturn(ppPayload, VERR_INVALID_POINTER); 373 389 LogFlowFuncEnter(); 374 390 … … 425 441 * @param pSource Event source of event to release. 426 442 * @param idEvent ID of event to release. 443 * 444 * @todo r=bird: The two places this is currently used make my head explode. 445 * First you release then you unregister it. Unregister frees is 446 * unconditionally. 447 * 448 * Any sane thinking person would assume that after we've release our 449 * reference to the @a idEvent, we cannot touch it any more because we 450 * don't have a valid reference any more. So, when ShClEventUnregister 451 * is then called and unconditionally frees the event: Boooooom! 452 * 453 * The locking interface here is generally not sane either, as the 454 * locking isn't done on the @a pSource but something the caller needs 455 * implements. Since we don't have access to the lock we cannot verify 456 * the locking protocol nor can we implement it (like in 457 * ShClEventWait). 458 * 459 * A better interface would return PSHCLEVENT instead of SHCLEVENTID, 460 * and then you could work directly on that as an object, rather via a 461 * slow object list. It would eliminate shclEventGet and any though 462 * that someone might be updating the list while shclEventGet traverses 463 * it. 427 464 */ 428 465 uint32_t ShClEventRelease(PSHCLEVENTSOURCE pSource, SHCLEVENTID idEvent) 429 466 { 430 467 PSHCLEVENT pEvent = shclEventGet(pSource, idEvent); 431 if (!pEvent) 432 { 433 AssertFailed(); 434 return UINT32_MAX; 435 } 436 468 AssertReturn(pEvent, UINT32_MAX); 437 469 AssertReturn(pEvent->cRefs, UINT32_MAX); /* Sanity. Yeah, not atomic. */ 438 470 … … 446 478 * @param pSource Event source of event to signal. 447 479 * @param uID Event ID to signal. 448 * @param pPayload Event payload to associate. Takes ownership. Optional. 480 * @param pPayload Event payload to associate. Takes ownership on 481 * success. Optional. 449 482 * 450 483 * @note Caller must enter crit sect protecting the event source! 451 484 */ 452 int ShClEventSignal(PSHCLEVENTSOURCE pSource, SHCLEVENTID uID, 453 PSHCLEVENTPAYLOAD pPayload) 485 int ShClEventSignal(PSHCLEVENTSOURCE pSource, SHCLEVENTID uID, PSHCLEVENTPAYLOAD pPayload) 454 486 { 455 487 AssertPtrReturn(pSource, VERR_INVALID_POINTER); … … 467 499 468 500 rc = RTSemEventMultiSignal(pEvent->hEvtMulSem); 501 if (RT_FAILURE(rc)) 502 pEvent->pPayload = NULL; /* (no race condition if consumer also enters the critical section) */ 469 503 } 470 504 else
Note:
See TracChangeset
for help on using the changeset viewer.