VirtualBox

Changeset 14352 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Nov 19, 2008 2:10:24 PM (16 years ago)
Author:
vboxsync
Message:

Additions/HGCM: merged code for HGCMCall and HGCMCallTimed, as per todo

Location:
trunk/src/VBox/Additions
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/VBoxGuest/VBoxGuest.cpp

    r14219 r14352  
    341341
    342342#ifdef VBOX_WITH_HGCM
    343 DECLVBGL(void) VBoxHGCMCallback (VMMDevHGCMRequestHeader *pHeader, void *pvData, uint32_t u32Data)
    344 {
    345     PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pvData;
    346 
    347     dprintf(("VBoxHGCMCallback\n"));
    348 
     343void VBoxHGCMCallbackWorker (VMMDevHGCMRequestHeader *pHeader, PVBOXGUESTDEVEXT pDevExt,
     344                             uint32_t u32Timeout, bool fInterruptible)
     345{
    349346    /* Possible problem with request completion right between the fu32Flags check and KeWaitForSingleObject
    350347     * call; introduce a timeout to make sure we don't wait indefinitely.
    351348     */
    352349
     350    LARGE_INTEGER timeout;
     351    if (u32Timeout == RT_INDEFINITE_WAIT)
     352        timeout.QuadPart = pDevExt->HGCMWaitTimeout.QuadPart;
     353    else
     354        timeout.QuadPart = u32Timeout * -10000; /* relative in 100ns units */
    353355    while ((pHeader->fu32Flags & VBOX_HGCM_REQ_DONE) == 0)
    354356    {
    355         /* Specifying UserMode so killing the user process will abort the wait.
    356          * @todo Since VbglGRCancel is not yet implemented, the wait itself must
    357          *       be not interruptible. The wait can be interrupted only when the
    358          *       calling process is being killed.
    359          *       When alertable is TRUE, the wait sometimes ends with STATUS_USER_APC.
    360          */
     357        /* Specifying UserMode so killing the user process will abort the wait. */
    361358        NTSTATUS rc = KeWaitForSingleObject (&pDevExt->keventNotification, Executive,
    362359                                             UserMode,
    363                                              FALSE, /* Not Alertable */
    364                                              &pDevExt->HGCMWaitTimeout
     360                                             fInterruptible ? TRUE : FALSE, /* Alertable */
     361                                             &timeout
    365362                                            );
    366363        dprintf(("VBoxHGCMCallback: Wait returned %d fu32Flags=%x\n", rc, pHeader->fu32Flags));
    367364
    368         if (rc == STATUS_TIMEOUT)
     365        if (rc == STATUS_TIMEOUT && u32Timeout == RT_INDEFINITE_WAIT)
    369366            continue;
    370367
     
    380377}
    381378
    382 /* Note that VbglGRCancel *is* now implemented. */
    383 DECLVBGL(void) VBoxHGCMCallbackTimeout (VMMDevHGCMRequestHeader *pHeader, void *pvData, uint32_t u32Data)
     379DECLVBGL(void) VBoxHGCMCallback (VMMDevHGCMRequestHeader *pHeader, void *pvData, uint32_t u32Data)
    384380{
    385381    PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pvData;
    386     LARGE_INTEGER timeout;
    387     timeout.QuadPart = u32Data * -10000; /* relative in 100ns units */
    388     dprintf(("VBoxHGCMCallbackTimeout: entering, timeout %llu\n", timeout.QuadPart));
    389     NTSTATUS rc = KeWaitForSingleObject (&pDevExt->keventNotification, Executive,
    390                                          UserMode,
    391                                          FALSE, /* Not Alertable */
    392                                          &timeout
    393                                         );
    394     dprintf(("VBoxHGCMCallbackTimeout: Wait returned %d fu32Flags=%x\n", rc, pHeader->fu32Flags));
    395 
    396     if (rc != STATUS_WAIT_0)
    397         dprintf(("VBoxHGCMCallbackTimeout: The external event was signalled or the wait timed out or terminated rc = 0x%08X.\n", rc));
    398     else
    399         dprintf(("VBoxHGCMCallbackTimeout: fu32Flags = %08X\n", pHeader->fu32Flags));
    400     return;
     382
     383    dprintf(("VBoxHGCMCallback\n"));
     384    VBoxHGCMCallbackWorker (pHeader, pDevExt, u32Data, false);
     385}
     386
     387DECLVBGL(void) VBoxHGCMCallbackInterruptible (VMMDevHGCMRequestHeader *pHeader, void *pvData,
     388                                              uint32_t u32Data)
     389{
     390    PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pvData;
     391
     392    dprintf(("VBoxHGCMCallback\n"));
     393    VBoxHGCMCallbackWorker (pHeader, pDevExt, u32Data, true);
    401394}
    402395
     
    937930            dprintf(("a) ptr->u32ClientID = %d\n", ptr->u32ClientID));
    938931
    939             int rc = VbglHGCMConnect (ptr, VBoxHGCMCallback, pDevExt, 0);
     932            int rc = VbglHGCMConnect (ptr, VBoxHGCMCallback, pDevExt, RT_INDEFINITE_WAIT);
    940933
    941934            dprintf(("b) ptr->u32ClientID = %d\n", ptr->u32ClientID));
     
    980973             */
    981974
    982             int rc = VbglHGCMDisconnect (ptr, VBoxHGCMCallback, pDevExt, 0);
     975            int rc = VbglHGCMDisconnect (ptr, VBoxHGCMCallback, pDevExt, RT_INDEFINITE_WAIT);
    983976
    984977            if (RT_FAILURE(rc))
     
    10091002            VBoxGuestHGCMCallInfo *ptr = (VBoxGuestHGCMCallInfo *)pBuf;
    10101003
    1011             int rc = VbglHGCMCall (ptr, VBoxHGCMCallback, pDevExt, 0);
     1004            int rc = VbglHGCMCall (ptr, VBoxHGCMCallback, pDevExt, RT_INDEFINITE_WAIT);
    10121005
    10131006            if (RT_FAILURE(rc))
     
    10231016        } break;
    10241017
    1025         case VBOXGUEST_IOCTL_HGCM_CALL_TIMEOUT(0): /* (The size isn't relevant on NT.) */
    1026         {
    1027             dprintf(("VBoxGuest::VBoxGuestDeviceControl: VBOXGUEST_IOCTL_HGCM_CALL_TIMEOUT\n"));
     1018        case VBOXGUEST_IOCTL_HGCM_CALL_TIMED(0): /* (The size isn't relevant on NT.) */
     1019        {
     1020            dprintf(("VBoxGuest::VBoxGuestDeviceControl: VBOXGUEST_IOCTL_HGCM_CALL_TIMED\n"));
    10281021
    10291022            Status = vboxHGCMVerifyIOBuffers (pStack,
    1030                                               sizeof (VBoxGuestHGCMCallInfoTimeout));
     1023                                              sizeof (VBoxGuestHGCMCallInfoTimed));
    10311024
    10321025            if (Status != STATUS_SUCCESS)
     
    10361029            }
    10371030
    1038             VBoxGuestHGCMCallInfoTimeout *pInfo = (VBoxGuestHGCMCallInfoTimeout *)pBuf;
     1031            VBoxGuestHGCMCallInfoTimed *pInfo = (VBoxGuestHGCMCallInfoTimed *)pBuf;
    10391032            VBoxGuestHGCMCallInfo *ptr = &pInfo->info;
    10401033
    10411034            int rc;
    1042             if (pInfo->u32Timeout == RT_INDEFINITE_WAIT)
    1043             {
    1044                 dprintf(("VBoxGuest::VBoxGuestDeviceControl: calling VBoxHGCMCall with no timeout\n"));
    1045                 rc = VbglHGCMCall (ptr, VBoxHGCMCallback, pDevExt, 0);
     1035            if (pInfo->fInterruptible)
     1036            {
     1037                dprintf(("VBoxGuest::VBoxGuestDeviceControl: calling VBoxHGCMCall interruptible, timeout %lu ms\n",
     1038                         pInfo->u32Timeout));
     1039                rc = VbglHGCMCall (ptr, VBoxHGCMCallbackInterruptible, pDevExt, pInfo->u32Timeout);
    10461040            }
    10471041            else
    10481042            {
    1049                 dprintf(("VBoxGuest::VBoxGuestDeviceControl: calling VBoxHGCMCall timeout %lu ms\n",
     1043                dprintf(("VBoxGuest::VBoxGuestDeviceControl: calling VBoxHGCMCall, timeout %lu ms\n",
    10501044                         pInfo->u32Timeout));
    1051                 rc = VbglHGCMCall (ptr, VBoxHGCMCallbackTimeout, pDevExt, pInfo->u32Timeout);
     1045                rc = VbglHGCMCall (ptr, VBoxHGCMCallback, pDevExt, pInfo->u32Timeout);
    10521046            }
    10531047
    10541048            if (RT_FAILURE(rc))
    10551049            {
    1056                 dprintf(("VBOXGUEST_IOCTL_HGCM_CALL_TIMEOUT: vbox rc = %Rrc\n", rc));
     1050                dprintf(("VBOXGUEST_IOCTL_HGCM_CALL_TIMED: vbox rc = %Rrc\n", rc));
    10571051                Status = STATUS_UNSUCCESSFUL;
    10581052            }
  • trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp

    r14316 r14352  
    389389            pSession->aHGCMClientIds[i] = 0;
    390390            Log(("VBoxGuestCloseSession: disconnecting client id %#RX32\n", Info.u32ClientID));
    391             VbglHGCMDisconnect(&Info, VBoxGuestHGCMAsyncWaitCallback, pDevExt, false /* uninterruptible */);
     391            VbglHGCMDisconnect(&Info, VBoxGuestHGCMAsyncWaitCallback, pDevExt, RT_INDEFINITE_WAIT);
    392392        }
    393393#endif
     
    910910}
    911911
    912 
    913912/**
    914913 * This is a callback for dealing with async waits.
     
    918917static DECLCALLBACK(void) VBoxGuestHGCMAsyncWaitCallback(VMMDevHGCMRequestHeader *pHdr, void *pvUser, uint32_t u32User)
    919918{
    920     const bool fInterruptible = (bool)u32User;
    921919    PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pvUser;
    922920    LogFunc(("requestType=%d\n", pHdr->header.requestType));
    923     VBoxGuestHGCMAsyncWaitCallbackWorker((VMMDevHGCMRequestHeader volatile *)pHdr, pDevExt, fInterruptible, RT_INDEFINITE_WAIT);
    924 }
    925 
     921    VBoxGuestHGCMAsyncWaitCallbackWorker((VMMDevHGCMRequestHeader volatile *)pHdr,
     922                                         pDevExt, false /* fInterruptible */,
     923                                         RT_INDEFINITE_WAIT);
     924}
    926925
    927926/**
     
    930929 * It operates in a manner similar to VBoxGuestCommonIOCtl_WaitEvent.
    931930 */
    932 static DECLCALLBACK(void) VBoxGuestHGCMAsyncWaitCallbackTimeoutInterruptible(VMMDevHGCMRequestHeader *pHdr, void *pvUser, uint32_t u32User)
     931static DECLCALLBACK(void) VBoxGuestHGCMAsyncWaitCallbackInterruptible(VMMDevHGCMRequestHeader *pHdr,
     932                                                   void *pvUser, uint32_t u32User)
    933933{
    934934    PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pvUser;
    935935    LogFunc(("requestType=%d\n", pHdr->header.requestType));
    936     VBoxGuestHGCMAsyncWaitCallbackWorker((VMMDevHGCMRequestHeader volatile *)pHdr, pDevExt, true /* fInterruptible */, u32User);
    937 }
    938 
    939 
    940 /**
    941  * This is an uninterruptible callback for dealing with async waits with a timeout.
    942  *
    943  * It operates in a manner similar to VBoxGuestCommonIOCtl_WaitEvent.
    944  */
    945 static DECLCALLBACK(void) VBoxGuestHGCMAsyncWaitCallbackTimeout(VMMDevHGCMRequestHeader *pHdr, void *pvUser, uint32_t u32User)
    946 {
    947     PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pvUser;
    948     LogFunc(("requestType=%d\n", pHdr->header.requestType));
    949     VBoxGuestHGCMAsyncWaitCallbackWorker((VMMDevHGCMRequestHeader volatile *)pHdr, pDevExt, false /* fInterruptible */, u32User);
    950 }
    951 
     936    VBoxGuestHGCMAsyncWaitCallbackWorker((VMMDevHGCMRequestHeader volatile *)pHdr,
     937                                         pDevExt, true /* fInterruptible */,
     938                                         u32User);
     939}
    952940
    953941static int VBoxGuestCommonIOCtl_HGCMConnect(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, VBoxGuestHGCMConnectInfo *pInfo,
     
    963951         ? pInfo->Loc.u.host.achName : "<not local host>"));
    964952
    965     int rc = VbglHGCMConnect(pInfo, VBoxGuestHGCMAsyncWaitCallback, pDevExt, false /* uninterruptible */);
     953    int rc = VbglHGCMConnect(pInfo, VBoxGuestHGCMAsyncWaitCallback, pDevExt, RT_INDEFINITE_WAIT);
    966954    if (RT_SUCCESS(rc))
    967955    {
     
    993981                Info.result = 0;
    994982                Info.u32ClientID = pInfo->u32ClientID;
    995                 VbglHGCMDisconnect(&Info, VBoxGuestHGCMAsyncWaitCallback, pDevExt, false /* uninterruptible */);
     983                VbglHGCMDisconnect(&Info, VBoxGuestHGCMAsyncWaitCallback, pDevExt, RT_INDEFINITE_WAIT);
    996984                return VERR_TOO_MANY_OPEN_FILES;
    997985            }
     
    10351023     */
    10361024    Log(("VBoxGuestCommonIOCtl: HGCM_DISCONNECT: u32Client=%RX32\n", pInfo->u32ClientID));
    1037     int rc = VbglHGCMDisconnect(pInfo, VBoxGuestHGCMAsyncWaitCallback, pDevExt, false /* uninterruptible */);
     1025    int rc = VbglHGCMDisconnect(pInfo, VBoxGuestHGCMAsyncWaitCallback, pDevExt, RT_INDEFINITE_WAIT);
    10381026    if (RT_SUCCESS(rc))
    10391027    {
     
    10531041
    10541042
    1055 /** @remarks Identical to VBoxGuestCommonIOCtl_HGCMCallTimeout. */
    1056 static int VBoxGuestCommonIOCtl_HGCMCall(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, VBoxGuestHGCMCallInfo *pInfo,
     1043static int VBoxGuestCommonIOCtl_HGCMCall(PVBOXGUESTDEVEXT pDevExt,
     1044                                         PVBOXGUESTSESSION pSession,
     1045                                         VBoxGuestHGCMCallInfo *pInfo,
     1046                                         uint32_t u32Timeout, bool fInterruptible,
    10571047                                         size_t cbData, size_t *pcbDataReturned)
    10581048{
     
    10991089     */
    11001090    Log(("VBoxGuestCommonIOCtl: HGCM_CALL: u32Client=%RX32\n", pInfo->u32ClientID));
    1101     int rc = VbglHGCMCall(pInfo, VBoxGuestHGCMAsyncWaitCallback, pDevExt, pSession->R0Process != NIL_RTR0PROCESS);
     1091    int rc;
     1092    if (fInterruptible)
     1093        rc = VbglHGCMCall(pInfo, VBoxGuestHGCMAsyncWaitCallbackInterruptible, pDevExt,
     1094                          u32Timeout);
     1095    else
     1096        rc = VbglHGCMCall(pInfo, VBoxGuestHGCMAsyncWaitCallback, pDevExt, u32Timeout);
    11021097    if (RT_SUCCESS(rc))
    11031098    {
     
    11101105}
    11111106
    1112 
    1113 # ifdef HGCM_TIMEOUT
    1114 /** @remarks Identical to VBoxGuestCommonIOCtl_HGCMCall.
    1115  * @todo r=bird: merge the two.  */
    1116 static int VBoxGuestCommonIOCtl_HGCMCallTimeout(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, VBoxGuestHGCMCallInfoTimeout *pInfoTimeout,
    1117                                                 size_t cbData, size_t *pcbDataReturned)
    1118 {
    1119     VBoxGuestHGCMCallInfo *pInfo = &pInfoTimeout->info;
    1120     /*
    1121      * Some more validations.
    1122      */
    1123     if (pInfo->cParms > 4096) /* (Just make sure it doesn't overflow the next check.) */
    1124     {
    1125         Log(("VBoxGuestCommonIOCtl: HGCM_CALL: cParm=%RX32 is not sane\n", pInfo->cParms));
    1126         return VERR_INVALID_PARAMETER;
    1127     }
    1128     const size_t cbActual = sizeof(*pInfoTimeout) + pInfo->cParms * sizeof(HGCMFunctionParameter);
    1129     if (cbData < cbActual)
    1130     {
    1131         Log(("VBoxGuestCommonIOCtl: HGCM_CALL: cbData=%#zx (%zu) required size is %#zx (%zu)\n",
    1132              cbData, cbActual));
    1133         return VERR_INVALID_PARAMETER;
    1134     }
    1135 
    1136     /*
    1137      * Validate the client id.
    1138      */
    1139     const uint32_t u32ClientId = pInfo->u32ClientID;
    1140     unsigned i;
    1141     RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
    1142     RTSpinlockAcquireNoInts(pDevExt->SessionSpinlock, &Tmp);
    1143     for (i = 0; i < RT_ELEMENTS(pSession->aHGCMClientIds); i++)
    1144         if (pSession->aHGCMClientIds[i] == u32ClientId)
    1145             break;
    1146     RTSpinlockReleaseNoInts(pDevExt->SessionSpinlock, &Tmp);
    1147     if (RT_UNLIKELY(i >= RT_ELEMENTS(pSession->aHGCMClientIds)))
    1148     {
    1149         static unsigned s_cErrors = 0;
    1150         if (s_cErrors++ > 32)
    1151             LogRel(("VBoxGuestCommonIOCtl: HGCM_CALL: Invalid handle. u32Client=%RX32\n", u32ClientId));
    1152         return VERR_INVALID_HANDLE;
    1153     }
    1154 
    1155     /*
    1156      * The VbglHGCMCall call will invoke the callback if the HGCM
    1157      * call is performed in an ASYNC fashion. This function can
    1158      * deal with cancelled requests, so we let user more requests
    1159      * be interruptible (should add a flag for this later I guess).
    1160      */
    1161     Log(("VBoxGuestCommonIOCtl: HGCM_CALL: u32Client=%RX32\n", pInfo->u32ClientID));
    1162     int rc;
    1163     if (pSession->R0Process == NIL_RTR0PROCESS)
    1164         rc = VbglHGCMCall(pInfo, VBoxGuestHGCMAsyncWaitCallbackTimeout, pDevExt, pInfoTimeout->u32Timeout);
    1165     else
    1166         rc = VbglHGCMCall(pInfo, VBoxGuestHGCMAsyncWaitCallbackTimeoutInterruptible, pDevExt,
    1167                           pInfoTimeout->u32Timeout);
    1168     if (RT_SUCCESS(rc))
    1169     {
    1170         Log(("VBoxGuestCommonIOCtl: HGCM_CALL: result=%Rrc\n", pInfo->result));
    1171         if (pcbDataReturned)
    1172             *pcbDataReturned = cbActual;
    1173     }
    1174     Log(("VBoxGuestCommonIOCtl: HGCM_CALL: Failed. rc=%Rrc.\n", rc));
    1175     return rc;
    1176 }
    1177 # endif /* HGCM_TIMEOUT */
    1178 
    1179 
    11801107/**
    11811108 * @returns VBox status code. Unlike the other HGCM IOCtls this will combine
     
    11961123        Info.result = (uint32_t)VERR_WRONG_ORDER;           /** @todo Vitali, why is this member unsigned? */
    11971124        Info.u32ClientID = pDevExt->u32ClipboardClientId;
    1198         rc = VbglHGCMDisconnect(&Info, VBoxGuestHGCMAsyncWaitCallback, pDevExt, 0);
     1125        rc = VbglHGCMDisconnect(&Info, VBoxGuestHGCMAsyncWaitCallback, pDevExt, RT_INDEFINITE_WAIT);
    11991126        if (RT_SUCCESS(rc))
    12001127        {
     
    12191146    Info.result = (uint32_t)VERR_WRONG_ORDER;
    12201147
    1221     rc = VbglHGCMConnect(&Info, VBoxGuestHGCMAsyncWaitCallback, pDevExt, 0);
     1148    rc = VbglHGCMConnect(&Info, VBoxGuestHGCMAsyncWaitCallback, pDevExt, RT_INDEFINITE_WAIT);
    12221149    if (RT_FAILURE(rc))
    12231150    {
     
    13231250     * These ones are tricky and can be done later.
    13241251     */
    1325 /**@todo r=bird: Merge the handling of these two. The only difference is that the 2nd has one or two extra argument preceeding the call info. */
    13261252    else if (VBOXGUEST_IOCTL_STRIP_SIZE(iFunction) == VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL(0)))
    13271253    {
    13281254        CHECKRET_MIN_SIZE("HGCM_CALL", sizeof(VBoxGuestHGCMCallInfo));
    1329         rc = VBoxGuestCommonIOCtl_HGCMCall(pDevExt, pSession, (VBoxGuestHGCMCallInfo *)pvData, cbData, pcbDataReturned);
    1330     }
    1331 # ifdef HGCM_TIMEOUT
    1332     else if (VBOXGUEST_IOCTL_STRIP_SIZE(iFunction) == VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL_TIMEOUT(0)))
    1333     {
    1334         CHECKRET_MIN_SIZE("HGCM_CALL_TIMEOUT", sizeof(VBoxGuestHGCMCallInfoTimeout));
    1335         rc = VBoxGuestCommonIOCtl_HGCMCallTimeout(pDevExt, pSession, (VBoxGuestHGCMCallInfoTimeout *)pvData, cbData, pcbDataReturned);
    1336     }
    1337 # endif /* HGCM_TIMEOUT */
     1255        bool fInterruptible = pSession->R0Process != NIL_RTR0PROCESS;
     1256        rc = VBoxGuestCommonIOCtl_HGCMCall(pDevExt, pSession, (VBoxGuestHGCMCallInfo *)pvData,
     1257                                           RT_INDEFINITE_WAIT, fInterruptible,
     1258                                           cbData, pcbDataReturned);
     1259    }
     1260    else if (VBOXGUEST_IOCTL_STRIP_SIZE(iFunction) == VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL_TIMED(0)))
     1261    {
     1262        CHECKRET_MIN_SIZE("HGCM_CALL_TIMED", sizeof(VBoxGuestHGCMCallInfoTimed));
     1263        VBoxGuestHGCMCallInfoTimed *pInfo = (VBoxGuestHGCMCallInfoTimed *)pvData;
     1264        rc = VBoxGuestCommonIOCtl_HGCMCall(pDevExt, pSession, &pInfo->info,
     1265                                           pInfo->u32Timeout, !!pInfo->fInterruptible,
     1266                                           cbData, pcbDataReturned);
     1267    }
    13381268#endif /* VBOX_WITH_HGCM */
    13391269    else if (VBOXGUEST_IOCTL_STRIP_SIZE(iFunction) == VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_LOG(0)))
  • trunk/src/VBox/Additions/common/VBoxGuestLib/HGCM.cpp

    r14207 r14352  
    187187}
    188188
    189 DECLVBGL(int) VbglHGCMCallTimeout (VBGLHGCMHANDLE handle,
    190                                    VBoxGuestHGCMCallInfoTimeout *pData, uint32_t cbData)
     189DECLVBGL(int) VbglHGCMCallTimed (VBGLHGCMHANDLE handle,
     190                                 VBoxGuestHGCMCallInfoTimed *pData, uint32_t cbData)
    191191{
    192192    int rc = VINF_SUCCESS;
    193193
    194     VBGL_HGCM_ASSERTMsg(cbData >= sizeof (VBoxGuestHGCMCallInfoTimeout) + pData->info.cParms * sizeof (HGCMFunctionParameter),
    195                         ("cbData = %d, cParms = %d (calculated size %d)\n", cbData, pData->info.cParms, sizeof (VBoxGuestHGCMCallInfoTimeout) + pData->info.cParms * sizeof (VBoxGuestHGCMCallInfo)));
    196 
    197     if (pData->u32Timeout == RT_INDEFINITE_WAIT)
    198     {
    199         uint32_t cbDataNew = cbData - RT_OFFSETOF(VBoxGuestHGCMCallInfoTimeout, info);
    200         rc = vbglDriverIOCtl (&handle->driver, VBOXGUEST_IOCTL_HGCM_CALL(cbDataNew), &pData->info,
    201                               cbDataNew);
    202     }
    203     else
    204         rc = vbglDriverIOCtl (&handle->driver, VBOXGUEST_IOCTL_HGCM_CALL_TIMEOUT(cbData), pData, cbData);
     194    uint32_t cbExpected =   sizeof (VBoxGuestHGCMCallInfoTimed)
     195                          + pData->info.cParms * sizeof (HGCMFunctionParameter);
     196    VBGL_HGCM_ASSERTMsg(cbData >= cbExpected,
     197                        ("cbData = %d, cParms = %d (calculated size %d)\n",
     198                        cbData, pData->info.cParms, cbExpected));
     199
     200    rc = vbglDriverIOCtl (&handle->driver, VBOXGUEST_IOCTL_HGCM_CALL_TIMED(cbData),
     201                          pData, cbData);
    205202
    206203    return rc;
  • trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestProp.cpp

    r14214 r14352  
    846846    Msg.size.SetUInt32(0);
    847847
    848     int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL_TIMEOUT(sizeof(Msg)), &Msg, sizeof(Msg));
     848    int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL_TIMED(sizeof(Msg)), &Msg, sizeof(Msg));
    849849    if (RT_SUCCESS(rc))
    850850        rc = Msg.hdr.info.result;
  • trunk/src/VBox/Additions/linux/module/cmc.c

    r14304 r14352  
    3131{
    3232    VBoxDevice *dev = pvData;
    33     wait_event (dev->eventq, pHeader->fu32Flags & VBOX_HGCM_REQ_DONE);
     33    if (u32Data == RT_INDEFINITE_WAIT)
     34        wait_event (dev->eventq, pHeader->fu32Flags & VBOX_HGCM_REQ_DONE);
     35    else
     36        wait_event_timeout (dev->eventq, pHeader->fu32Flags & VBOX_HGCM_REQ_DONE,
     37                            msecs_to_jiffies (u32Data));
    3438}
    3539
     
    3842{
    3943    VBoxDevice *dev = pvData;
    40     wait_event_interruptible (dev->eventq, pHeader->fu32Flags & VBOX_HGCM_REQ_DONE);
    41 }
    42 
    43 static DECLVBGL(void)
    44 vboxadd_hgcm_callback_timeout (VMMDevHGCMRequestHeader *pHeader, void *pvData, uint32_t u32Data)
    45 {
    46     VBoxDevice *dev = pvData;
    47     wait_event_interruptible_timeout (dev->eventq, pHeader->fu32Flags & VBOX_HGCM_REQ_DONE,
    48                                       msecs_to_jiffies (u32Data));
     44    if (u32Data == RT_INDEFINITE_WAIT)
     45        wait_event_interruptible (dev->eventq, pHeader->fu32Flags & VBOX_HGCM_REQ_DONE);
     46    else
     47        wait_event_interruptible_timeout (dev->eventq, pHeader->fu32Flags & VBOX_HGCM_REQ_DONE,
     48                                          msecs_to_jiffies (u32Data));
    4949}
    5050
     
    5656    if (   VBOXGUEST_IOCTL_STRIP_SIZE(func)
    5757        == VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL(0)))
    58         rc = VbglHGCMCall (data, vboxadd_hgcm_callback_interruptible, opaque, 0);
     58        rc = VbglHGCMCall (data, vboxadd_hgcm_callback_interruptible, opaque, RT_INDEFINITE_WAIT);
    5959    /* this function can handle cancelled requests */
    6060    else if (   VBOXGUEST_IOCTL_STRIP_SIZE(func)
    61              == VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL_TIMEOUT(0)))
     61             == VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL_TIMED(0)))
    6262    {
    63         VBoxGuestHGCMCallInfoTimeout *pCallInfo;
    64         pCallInfo = (VBoxGuestHGCMCallInfoTimeout *) data;
    65         rc = VbglHGCMCall (&pCallInfo->info, vboxadd_hgcm_callback_timeout,
    66                            opaque, pCallInfo->u32Timeout);
     63        VBoxGuestHGCMCallInfoTimed *pCallInfo;
     64        pCallInfo = (VBoxGuestHGCMCallInfoTimed *) data;
     65        if (pCallInfo->fInterruptible)
     66            rc = VbglHGCMCall (&pCallInfo->info, vboxadd_hgcm_callback_interruptible,
     67                               opaque, pCallInfo->u32Timeout);
     68        else
     69            rc = VbglHGCMCall (&pCallInfo->info, vboxadd_hgcm_callback,
     70                               opaque, pCallInfo->u32Timeout);
    6771    }
    6872    else switch (func)
     
    7074        /* this function can NOT handle cancelled requests */
    7175        case VBOXGUEST_IOCTL_HGCM_CONNECT:
    72             rc = VbglHGCMConnect (data, vboxadd_hgcm_callback, opaque, 0);
     76            rc = VbglHGCMConnect (data, vboxadd_hgcm_callback, opaque, RT_INDEFINITE_WAIT);
    7377            break;
    7478
    7579        /* this function can NOT handle cancelled requests */
    7680        case VBOXGUEST_IOCTL_HGCM_DISCONNECT:
    77             rc = VbglHGCMDisconnect (data, vboxadd_hgcm_callback, opaque, 0);
     81            rc = VbglHGCMDisconnect (data, vboxadd_hgcm_callback, opaque, RT_INDEFINITE_WAIT);
    7882            break;
    7983
  • trunk/src/VBox/Additions/linux/module/vboxmod.c

    r14218 r14352  
    420420 * @param  u32Size        the size of the userspace structure
    421421 */
    422 static int vboxadd_hgcm_call_timeout(unsigned long userspace_info,
     422static int vboxadd_hgcm_call_timed(unsigned long userspace_info,
    423423                                     uint32_t u32Size)
    424424{
    425         VBoxGuestHGCMCallInfoTimeout *pInfo = NULL;
     425        VBoxGuestHGCMCallInfoTimed *pInfo = NULL;
    426426        int rc = 0;
    427427       
     
    445445                LogRelFunc(("client ID %u\n", pInfo->info.u32ClientID));
    446446                vrc = vboxadd_cmc_call(vboxDev,
    447                               VBOXGUEST_IOCTL_HGCM_CALL_TIMEOUT(u32Size), pInfo);
     447                              VBOXGUEST_IOCTL_HGCM_CALL_TIMED(u32Size), pInfo);
    448448                rc = -RTErrConvertToErrno(vrc);
    449449                if (   rc >= 0
     
    624624                IOCTL_EXIT("VBOXGUEST_IOCTL_HGCM_CALL", arg);
    625625        }
    626         else if (   VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL_TIMEOUT(0))
     626        else if (   VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL_TIMED(0))
    627627                 == VBOXGUEST_IOCTL_STRIP_SIZE(cmd))
    628628        {
    629629        /* Do the HGCM call using the Vbgl bits */
    630                 IOCTL_ENTRY("VBOXGUEST_IOCTL_HGCM_CALL_TIMEOUT", arg);
    631                 rc = vboxadd_hgcm_call_timeout(arg, _IOC_SIZE(cmd));
    632                 IOCTL_EXIT("VBOXGUEST_IOCTL_HGCM_CALL_TIMEOUT", arg);
     630                IOCTL_ENTRY("VBOXGUEST_IOCTL_HGCM_CALL_TIMED", arg);
     631                rc = vboxadd_hgcm_call_timed(arg, _IOC_SIZE(cmd));
     632                IOCTL_EXIT("VBOXGUEST_IOCTL_HGCM_CALL_TIMED", arg);
    633633        }
    634634        else
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