VirtualBox

Changeset 100461 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Jul 10, 2023 2:23:36 PM (17 months ago)
Author:
vboxsync
Message:

Shared Clipboard: More fine-grained control for Windows data object uninit vs. destruction. bugref:9437

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/GuestHost/SharedClipboard/ClipboardDataObjectImpl-win.cpp

    r100412 r100461  
    6262    , m_pStream(NULL)
    6363    , m_uObjIdx(0)
    64     , m_fThreadRunning(false)
    6564    , m_EventListComplete(NIL_RTSEMEVENT)
    6665    , m_EventStatusChanged(NIL_RTSEMEVENT)
     
    180179
    181180/**
    182  * Destroys a data object instance.
    183  */
    184 void SharedClipboardWinDataObject::Destroy(void)
     181 * Uninitialized a data object instance, internal version.
     182 */
     183void SharedClipboardWinDataObject::uninitInternal(void)
    185184{
    186185    LogFlowFuncEnter();
    187186
    188     AssertReturnVoid(m_lRefCount == 0);
     187    /* Let waiters know. */
     188    setStatusLocked(Uninitialized, VINF_SUCCESS);
    189189
    190190    /* Make sure to release the transfer. */
    191191    setTransferLocked(NULL);
     192}
     193
     194/**
     195 * Uninitialized a data object instance.
     196 */
     197void SharedClipboardWinDataObject::Uninit(void)
     198{
     199    LogFlowFuncEnter();
     200
     201    lock();
     202
     203    uninitInternal();
     204
     205    unlock();
     206}
     207
     208/**
     209 * Destroys a data object instance.
     210 */
     211void SharedClipboardWinDataObject::Destroy(void)
     212{
     213    LogFlowFuncEnter();
     214
     215    if (m_enmStatus == Uninitialized) /* Crit sect not available anymore. */
     216        return;
     217
     218    lock();
     219
     220    uninitInternal();
     221
     222    unlock();
    192223
    193224    int rc = RTCritSectDelete(&m_CritSect);
     
    236267    }
    237268    m_lstEntries.clear();
    238 
    239     m_enmStatus = Uninitialized;
    240     m_fThreadRunning = false;
    241     m_pTransfer = NULL;
    242269}
    243270
     
    390417                                        objEntry.objInfo = *pFsObjInfo;
    391418
     419                                        lock();
    392420                                        m_lstEntries.push_back(objEntry); /** @todo Can this throw? */
     421                                        unlock();
    393422                                    }
    394423                                    else /* Not fatal, just skip. */
     
    477506                objEntry.objInfo = *pFsObjInfo;
    478507
     508                pThis->lock();
    479509                pThis->m_lstEntries.push_back(objEntry); /** @todo Can this throw? */
     510                pThis->unlock();
    480511
    481512                rc = pThis->readDir(pTransfer, pRootEntry->pszName);
     
    488519                objEntry.objInfo = *pFsObjInfo;
    489520
     521                pThis->lock();
    490522                pThis->m_lstEntries.push_back(objEntry); /** @todo Can this throw? */
     523                pThis->unlock();
    491524            }
    492525            else
     
    516549             * This in turn then will create IStream instances (by the OS) for each file system object to handle.
    517550             */
    518             int rc2 = RTSemEventSignal(pThis->m_EventListComplete);
    519             AssertRC(rc2);
    520 
    521             if (pThis->m_lstEntries.size())
     551            rc = RTSemEventSignal(pThis->m_EventListComplete);
     552            if (RT_SUCCESS(rc))
    522553            {
     554                pThis->lock();
     555
     556                AssertReleaseMsg(pThis->m_lstEntries.size(),
     557                                 ("Shared Clipboard: No transfer root entries found -- should not happen, please file a bug report\n"));
     558
    523559                LogRel2(("Shared Clipboard: Waiting for transfer to complete ...\n"));
    524560
    525                 /* Transferring stuff can take a while, so don't use any timeout here. */
    526                 rc2 = RTSemEventWait(pThis->m_EventStatusChanged, RT_INDEFINITE_WAIT);
    527                 AssertRC(rc2);
    528 
    529                 switch (pThis->m_enmStatus)
     561                for (;;)
    530562                {
    531                     case Completed:
    532                         LogRel2(("Shared Clipboard: Transfer complete\n"));
     563                    pThis->unlock();
     564
     565                    /* Transferring stuff can take a while, so don't use any timeout here. */
     566                    rc = RTSemEventWait(pThis->m_EventStatusChanged, RT_INDEFINITE_WAIT);
     567
     568                    pThis->lock();
     569
     570                    if (RT_FAILURE(rc))
    533571                        break;
    534572
    535                     case Canceled:
    536                         LogRel2(("Shared Clipboard: Transfer canceled\n"));
    537                         break;
    538 
    539                     case Error:
    540                         LogRel2(("Shared Clipboard: Transfer error occurred\n"));
    541                         break;
    542 
    543                     default:
    544                         break;
     573                    switch (pThis->m_enmStatus)
     574                    {
     575                        case Uninitialized: /* Can happen due to transfer erros. */
     576                            LogRel2(("Shared Clipboard: Data object was unitialized\n"));
     577                            break;
     578
     579                        case Initialized:
     580                            AssertFailed(); /* State machine error -- debug this! */
     581                            break;
     582
     583                        case Running:
     584                            continue;
     585
     586                        case Completed:
     587                            LogRel2(("Shared Clipboard: Transfer complete\n"));
     588                            break;
     589
     590                        case Canceled:
     591                            LogRel2(("Shared Clipboard: Transfer canceled\n"));
     592                            break;
     593
     594                        case Error:
     595                            LogRel(("Shared Clipboard: Transfer error within data object thread occurred\n"));
     596                            break;
     597
     598                        default:
     599                            AssertFailed();
     600                            break;
     601                    }
     602
     603                    break;
    545604                }
     605
     606                pThis->unlock();
    546607            }
    547             else
    548                LogRel(("Shared Clipboard: No transfer root entries found -- should not happen, please file a bug report\n"));
    549         }
    550         else if (RT_FAILURE(rc))
    551             LogRel(("Shared Clipboard: Transfer failed with %Rrc\n", rc));
    552     }
     608        }
     609    }
     610
     611    if (RT_FAILURE(rc))
     612        LogRel(("Shared Clipboard: Transfer failed with %Rrc\n", rc));
    553613
    554614    LogFlowFuncLeaveRC(rc);
     
    707767    int rc = VINF_SUCCESS;
    708768
    709     if (   pFormatEtc->cfFormat == m_cfFileDescriptorA
     769    /* Pre-check -- see if the data object still is alive. */
     770    if (m_enmStatus == Uninitialized)
     771        rc = VERR_OBJECT_DESTROYED;
     772
     773    if (    RT_SUCCESS(rc)
     774        && (   pFormatEtc->cfFormat == m_cfFileDescriptorA
    710775#ifdef VBOX_CLIPBOARD_WITH_UNICODE_SUPPORT
    711         || pFormatEtc->cfFormat == m_cfFileDescriptorW
     776            || pFormatEtc->cfFormat == m_cfFileDescriptorW
    712777#endif
     778           )
    713779       )
    714780    {
     
    762828                RT_NOREF(enmTransferStatus);
    763829
    764                 LogFlowFunc(("FormatIndex_FileDescriptor%s, enmTransferStatus=%s, m_fRunning=%RTbool\n",
    765                              fUnicode ? "W" : "A", ShClTransferStatusToStr(enmTransferStatus), m_fThreadRunning));
     830                LogFlowFunc(("FormatIndex_FileDescriptor%s, enmTransferStatus=%s\n",
     831                             fUnicode ? "W" : "A", ShClTransferStatusToStr(enmTransferStatus)));
    766832
    767833                /* The caller can call GetData() several times, so make sure we don't do the same transfer multiple times. */
    768                 if (!m_fThreadRunning)
     834                if (ShClTransferGetStatus(m_pTransfer) != SHCLTRANSFERSTATUS_STARTED)
    769835                {
    770836                    /* Start the transfer + run it asynchronously in a separate thread. */
     
    775841                        if (RT_SUCCESS(rc))
    776842                        {
    777                             m_fThreadRunning = true;
    778 
    779843                            /* Leave lock while waiting. */
    780844                            unlock();
     
    782846                            /* Don't block for too long here, as this also will screw other apps running on the OS. */
    783847                            LogRel2(("Shared Clipboard: Waiting for IDataObject listing to arrive ...\n"));
    784                             rc = RTSemEventWait(m_EventListComplete, SHCL_TIMEOUT_DEFAULT_MS);
     848                            rc = RTSemEventWait(m_EventListComplete, RT_MS_10SEC);
    785849
    786850                            /* Re-acquire lock. */
    787851                            lock();
     852
     853                            if (   m_pTransfer == NULL
     854                                || m_enmStatus != Running) /* Still in running state? */
     855                            {
     856                                rc = VERR_OBJECT_DESTROYED;
     857                                break;
     858                            }
    788859                        }
    789860                    }
     
    807878            }
    808879
     880            case Completed:
     881                break;
     882
    809883            default:
     884                AssertFailedStmt(rc = VERR_STATE_CHANGED);
    810885                break;
    811886        }
     
    817892        }
    818893    }
     894
     895    Log2Func(("enmStatus=%#x, pTransfer=%p, rc=%Rrc\n", m_enmStatus, m_pTransfer, rc));
    819896
    820897    if (RT_SUCCESS(rc))
     
    868945    unlock();
    869946
    870     LogFlowFunc(("hr=%Rhrc\n", hr));
     947    LogFlowFunc(("LEAVE hr=%Rhrc\n", hr));
    871948    return hr;
    872949}
     
    10391116int SharedClipboardWinDataObject::setTransferLocked(PSHCLTRANSFER pTransfer)
    10401117{
     1118    AssertReturn(RTCritSectIsOwned(&m_CritSect), VERR_WRONG_ORDER);
     1119
    10411120    LogFlowFunc(("pTransfer=%p\n", pTransfer));
    10421121
     
    10561135                m_pTransfer = pTransfer;
    10571136
     1137                SharedClipboardWinTransferCtx *pWinURITransferCtx = (SharedClipboardWinTransferCtx *)pTransfer->pvUser;
     1138                AssertPtr(pWinURITransferCtx);
     1139
     1140                pWinURITransferCtx->pDataObj = this; /* Save a backref to this object. */
     1141
    10581142                ShClTransferAcquire(pTransfer);
    10591143            }
     
    10661150        if (m_pTransfer)
    10671151        {
     1152            SharedClipboardWinTransferCtx *pWinURITransferCtx = (SharedClipboardWinTransferCtx *)m_pTransfer->pvUser;
     1153            AssertPtr(pWinURITransferCtx);
     1154
     1155            pWinURITransferCtx->pDataObj = NULL; /* Release backref to this object. */
     1156
    10681157            ShClTransferRelease(m_pTransfer);
    10691158            m_pTransfer = NULL;
     1159
     1160            /* Make sure to notify any waiters. */
     1161            rc = RTSemEventSignal(m_EventListComplete);
     1162            AssertRC(rc);
    10701163        }
    10711164    }
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