VirtualBox

Changeset 100641 in vbox for trunk


Ignore:
Timestamp:
Jul 19, 2023 8:33:05 AM (19 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
158478
Message:

Shared Clipboard: Easier to follow event destruction handling: Destroy + de-allocate an event if its refcount reaches 0. bugref:9437

Location:
trunk/src/VBox
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/GuestHost/SharedClipboard/clipboard-common.cpp

    r100566 r100641  
    4949*********************************************************************************************************************************/
    5050static void shClEventSourceResetInternal(PSHCLEVENTSOURCE pSource);
     51static int shClEventSourceUnregisterEvent(PSHCLEVENTSOURCE pSource, PSHCLEVENT pEvent);
    5152
    5253static void shClEventDestroy(PSHCLEVENT pEvent);
     
    204205    RTListForEachSafe(&pSource->lstEvents, pEvIt, pEvItNext, SHCLEVENT, Node)
    205206    {
    206         RTListNodeRemove(&pEvIt->Node);
     207        bool const fDealloc = ASMAtomicReadU32(&pEvIt->cRefs) == 0; /* Still any references left? Skip de-allocation. */
     208        if (!fDealloc)
     209            Log3Func(("Event %RU32 has %RU32 references left, skipping de-allocation\n", pEvIt->idEvent, pEvIt->cRefs));
    207210
    208211        shClEventDestroy(pEvIt);
    209212
    210         RTMemFree(pEvIt);
    211         pEvIt = NULL;
     213        int rc2 = shClEventSourceUnregisterEvent(pSource, pEvIt);
     214        AssertRC(rc2);
     215
     216        if (fDealloc)
     217        {
     218            RTMemFree(pEvIt);
     219            pEvIt = NULL;
     220        }
    212221    }
    213222}
     
    304313        return;
    305314
    306     AssertMsgReturnVoid(pEvent->cRefs == 0, ("Event %RU32 still has %RU32 references\n",
    307                                              pEvent->idEvent, pEvent->cRefs));
    308 
    309315    LogFlowFunc(("Event %RU32\n", pEvent->idEvent));
    310316
     
    326332 * @returns VBox status code.
    327333 * @param   pSource             Event source to unregister event for.
    328  * @param   pEvent              Event to unregister. On success the pointer will be invalid.
    329  */
    330 static int shClEventSourceUnregisterEventInternal(PSHCLEVENTSOURCE pSource, PSHCLEVENT pEvent)
    331 {
     334 * @param   pEvent              Event to unregister.
     335 */
     336static int shClEventSourceUnregisterEvent(PSHCLEVENTSOURCE pSource, PSHCLEVENT pEvent)
     337{
     338    RT_NOREF(pSource);
     339
    332340    LogFlowFunc(("idEvent=%RU32, cRefs=%RU32\n", pEvent->idEvent, pEvent->cRefs));
    333341
    334     AssertReturn(pEvent->cRefs == 0, VERR_WRONG_ORDER);
    335 
    336     int rc = RTCritSectEnter(&pSource->CritSect);
    337     if (RT_SUCCESS(rc))
    338     {
    339         RTListNodeRemove(&pEvent->Node);
    340 
    341         shClEventDestroy(pEvent);
    342 
    343         rc = RTCritSectLeave(&pSource->CritSect);
    344         if (RT_SUCCESS(rc))
    345         {
    346             RTMemFree(pEvent);
    347             pEvent = NULL;
    348         }
    349     }
    350 
    351     return rc;
     342    RTListNodeRemove(&pEvent->Node);
     343    pEvent->pParent = NULL;
     344
     345    return VINF_SUCCESS;
    352346}
    353347
     
    522516
    523517/**
    524  * Releases event by decreasing its reference count. Will be destroys once the reference count reaches 0.
     518 * Releases event by decreasing its reference count. Will be destroyed once the reference count reaches 0.
    525519 *
    526520 * @returns New reference count, or UINT32_MAX if failed.
     
    539533    if (cRefs == 0)
    540534    {
    541         AssertPtr(pEvent->pParent);
    542         int rc2 = shClEventSourceUnregisterEventInternal(pEvent->pParent, pEvent);
    543         AssertRC(rc2);
    544 
    545         return RT_SUCCESS(rc2) ? 0 : UINT32_MAX;
     535        int rc;
     536        PSHCLEVENTSOURCE pParent = pEvent->pParent;
     537        if (   pParent
     538            && RTCritSectIsInitialized(&pParent->CritSect))
     539        {
     540            rc = RTCritSectEnter(&pParent->CritSect);
     541            if (RT_SUCCESS(rc))
     542            {
     543                rc = shClEventSourceUnregisterEvent(pParent, pEvent);
     544
     545                int rc2 = RTCritSectLeave(&pParent->CritSect);
     546                if (RT_SUCCESS(rc))
     547                    rc = rc2;
     548            }
     549        }
     550        else
     551            rc = VINF_SUCCESS;
     552
     553        if (RT_SUCCESS(rc))
     554        {
     555            shClEventDestroy(pEvent);
     556
     557            RTMemFree(pEvent);
     558            pEvent = NULL;
     559        }
     560
     561        return RT_SUCCESS(rc) ? 0 : UINT32_MAX;
    546562    }
    547563
  • trunk/src/VBox/HostServices/SharedClipboard/testcase/tstClipboardTransfers.cpp

    r100560 r100641  
    309309    RTTESTI_CHECK_RC_OK(ShClEventSourceGenerateAndRegisterEvent(&Source, &pEvent));
    310310    ShClEventSourceReset(&Source);
    311     RTTESTI_CHECK(ShClEventSourceGetLast(&Source) != NULL); /* Event still in, as it holds a reference. */
     311    RTTESTI_CHECK(ShClEventSourceGetLast(&Source) == NULL); /* Event still valid, but removed from the source. */
    312312    RTTESTI_CHECK(ShClEventRelease(pEvent) == 0);
    313313    RTTESTI_CHECK(ShClEventRelease(pEvent) == UINT32_MAX); /* Ref count already was 0, so returns UINT32_MAX. */
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