/* In some case (like compiz which doesn't provide us with clipping regions) we * have to make sure that *all* open OpenGL windows are clipped to the main * application window. This is done here when called from the event handler * which monitor bounding changes of the main window. */ static void crClipRootHelper(unsigned long key, void *data1, void *data2) { /* The window with id zero is the base window, which isn't displayed at * all. So ignore it. */ if (key > 0) { /* Fetch the actually window info & the user data */ WindowInfo *pWin = (WindowInfo *) data1; /* We need to assign the context with this window */ ContextInfo *context = renderspuGetWindowContext(pWin); if (context && context->context) { RTSemFastMutexRequest(render_spu.syncMutex); GLboolean result = render_spu.ws.aglSetCurrentContext(context->context); CHECK_AGL_RC (result, "Render SPU (crClipRootHelper): SetCurrentContext Failed"); if (result) { result = render_spu.ws.aglUpdateContext(context->context); CHECK_AGL_RC (result, "Render SPU (crClipRootHelper): UpdateContext Failed"); /* Update the clipping region */ renderspu_SystemWindowApplyVisibleRegion(pWin); } RTSemFastMutexRelease(render_spu.syncMutex); /* Make sure that the position is updated relative to the Qt main * view */ renderspu_SystemWindowPosition(pWin, pWin->x, pWin->y); } } }
VBOXDDU_DECL(int) VDDbgIoLogReqTypeGetNext(VDIOLOGGER hIoLogger, PVDDBGIOLOGREQ penmReq) { int rc = VINF_SUCCESS; PVDIOLOGGERINT pIoLogger = hIoLogger; AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE); AssertPtrReturn(penmReq, VERR_INVALID_POINTER); rc = RTSemFastMutexRequest(pIoLogger->hMtx); AssertRCReturn(rc, rc); if (pIoLogger->offReadNext == pIoLogger->offWriteNext) { *penmReq = VDDBGIOLOGREQ_INVALID; RTSemFastMutexRelease(pIoLogger->hMtx); return VERR_INVALID_STATE; } if (RT_SUCCESS(rc)) { Assert(pIoLogger->enmReqTypeNext != VDDBGIOLOGREQ_INVALID); *penmReq = pIoLogger->enmReqTypeNext; } RTSemFastMutexRelease(pIoLogger->hMtx); return rc; }
DECLINLINE(int) vbglHandleHeapEnter (void) { int rc = RTSemFastMutexRequest(g_vbgldata.mutexHGCMHandle); VBGL_HGCM_ASSERTMsg(RT_SUCCESS(rc), ("Failed to request handle heap mutex, rc = %Rrc\n", rc)); return rc; }
DECLINLINE(int) vboxPciDevLock(PVBOXRAWPCIINS pThis) { #ifdef VBOX_WITH_SHARED_PCI_INTERRUPTS RTSpinlockAcquire(pThis->hSpinlock); return VINF_SUCCESS; #else int rc = RTSemFastMutexRequest(pThis->hFastMtx); AssertRC(rc); return rc; #endif }
VBOXDDU_DECL(int) VDDbgIoLogEventGetStart(VDIOLOGGER hIoLogger, uint64_t *pidEvent, bool *pfAsync, uint64_t *poff, size_t *pcbIo, size_t cbBuf, void *pvBuf) { int rc = VINF_SUCCESS; PVDIOLOGGERINT pIoLogger = hIoLogger; AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE); AssertPtrReturn(pidEvent, VERR_INVALID_POINTER); AssertPtrReturn(pfAsync, VERR_INVALID_POINTER); AssertPtrReturn(poff, VERR_INVALID_POINTER); AssertPtrReturn(pcbIo, VERR_INVALID_POINTER); rc = RTSemFastMutexRequest(pIoLogger->hMtx); AssertRCReturn(rc, rc); if (pIoLogger->u32EventTypeNext == VDIOLOG_EVENT_START) { IoLogEntryStart Entry; rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext, &Entry, sizeof(Entry), NULL); if (RT_SUCCESS(rc)) { *pfAsync = RT_BOOL(Entry.u8AsyncIo); *pidEvent = RT_LE2H_U64(Entry.u64Id); *poff = RT_LE2H_U64(Entry.Io.u64Off); *pcbIo = RT_LE2H_U64(Entry.Io.u64IoSize); if ( pIoLogger->enmReqTypeNext == VDDBGIOLOGREQ_WRITE && (pIoLogger->fFlags & VDDBG_IOLOG_LOG_DATA_WRITTEN)) { /* Read data. */ if (cbBuf < *pcbIo) rc = VERR_BUFFER_OVERFLOW; else rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext + sizeof(Entry), pvBuf, *pcbIo, NULL); if (rc != VERR_BUFFER_OVERFLOW) pIoLogger->offReadNext += *pcbIo + sizeof(Entry); } else pIoLogger->offReadNext += sizeof(Entry); } } else rc = VERR_INVALID_STATE; if (RT_SUCCESS(rc)) pIoLogger->u32EventTypeNext = 0; RTSemFastMutexRelease(pIoLogger->hMtx); return rc; }
VBOXDDU_DECL(int) VDDbgIoLogEventTypeGetNext(VDIOLOGGER hIoLogger, VDIOLOGEVENT *penmEvent) { int rc = VINF_SUCCESS; PVDIOLOGGERINT pIoLogger = hIoLogger; AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE); AssertPtrReturn(penmEvent, VERR_INVALID_POINTER); rc = RTSemFastMutexRequest(pIoLogger->hMtx); AssertRCReturn(rc, rc); if (pIoLogger->offReadNext == pIoLogger->offWriteNext) { *penmEvent = VDIOLOGEVENT_END; RTSemFastMutexRelease(pIoLogger->hMtx); return VINF_SUCCESS; } if (!pIoLogger->u32EventTypeNext) { uint32_t abBuf[2]; rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext, &abBuf, sizeof(abBuf), NULL); if (RT_SUCCESS(rc)) { pIoLogger->u32EventTypeNext = abBuf[0]; pIoLogger->enmReqTypeNext = (VDDBGIOLOGREQ)abBuf[1]; } } if (RT_SUCCESS(rc)) { Assert(pIoLogger->u32EventTypeNext != VDIOLOGEVENT_INVALID); switch (pIoLogger->u32EventTypeNext) { case VDIOLOG_EVENT_START: *penmEvent = VDIOLOGEVENT_START; break; case VDIOLOG_EVENT_COMPLETE: *penmEvent = VDIOLOGEVENT_COMPLETE; break; default: AssertMsgFailed(("Invalid event type %d\n", pIoLogger->u32EventTypeNext)); } } RTSemFastMutexRelease(pIoLogger->hMtx); return rc; }
VBOXDDU_DECL(int) VDDbgIoLogEventGetComplete(VDIOLOGGER hIoLogger, uint64_t *pidEvent, int *pRc, uint64_t *pmsDuration, size_t *pcbIo, size_t cbBuf, void *pvBuf) { int rc = VINF_SUCCESS; PVDIOLOGGERINT pIoLogger = hIoLogger; AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE); AssertPtrReturn(pidEvent, VERR_INVALID_POINTER); AssertPtrReturn(pmsDuration, VERR_INVALID_POINTER); AssertPtrReturn(pcbIo, VERR_INVALID_POINTER); rc = RTSemFastMutexRequest(pIoLogger->hMtx); AssertRCReturn(rc, rc); if (pIoLogger->u32EventTypeNext == VDIOLOG_EVENT_COMPLETE) { IoLogEntryComplete Entry; rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext, &Entry, sizeof(Entry), NULL); if (RT_SUCCESS(rc)) { *pidEvent = RT_LE2H_U64(Entry.u64Id); *pRc = (int)RT_LE2H_U32((int32_t)Entry.i32Rc); *pmsDuration = RT_LE2H_U64(Entry.msDuration); *pcbIo = RT_LE2H_U64(Entry.u64IoBuffer); if (*pcbIo) { /* Read data. */ if (cbBuf < *pcbIo) rc = VERR_BUFFER_OVERFLOW; else rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext + sizeof(Entry), pvBuf, *pcbIo, NULL); if (rc != VERR_BUFFER_OVERFLOW) pIoLogger->offReadNext += *pcbIo + sizeof(Entry); } else pIoLogger->offReadNext += sizeof(Entry); } } else rc = VERR_INVALID_STATE; if (RT_SUCCESS(rc)) pIoLogger->u32EventTypeNext = 0; RTSemFastMutexRelease(pIoLogger->hMtx); return rc; }
/** * Destroys the given VUSB sniffer instance. * * @returns nothing. * @param hSniffer The sniffer instance to destroy. */ DECLHIDDEN(void) VUSBSnifferDestroy(VUSBSNIFFER hSniffer) { PVUSBSNIFFERINT pThis = hSniffer; int rc = RTSemFastMutexRequest(pThis->hMtx); AssertRC(rc); if (pThis->hFile != NIL_RTFILE) RTFileClose(pThis->hFile); if (pThis->pbBlockData) RTMemFree(pThis->pbBlockData); RTSemFastMutexRelease(pThis->hMtx); RTSemFastMutexDestroy(pThis->hMtx); RTMemFree(pThis); }
PUSBDEVICE USBProxyBackendUsbIp::getDevices(void) { PUSBDEVICE pFirst = NULL; PUSBDEVICE *ppNext = &pFirst; /* Create a deep copy of the device list. */ RTSemFastMutexRequest(m->hMtxDevices); PUSBDEVICE pCur = m->pUsbDevicesCur; while (pCur) { PUSBDEVICE pNew = (PUSBDEVICE)RTMemAllocZ(sizeof(USBDEVICE)); if (pNew) { pNew->pszManufacturer = RTStrDup(pCur->pszManufacturer); pNew->pszProduct = RTStrDup(pCur->pszProduct); if (pCur->pszSerialNumber) pNew->pszSerialNumber = RTStrDup(pCur->pszSerialNumber); pNew->pszBackend = RTStrDup(pCur->pszBackend); pNew->pszAddress = RTStrDup(pCur->pszAddress); pNew->idVendor = pCur->idVendor; pNew->idProduct = pCur->idProduct; pNew->bcdDevice = pCur->bcdDevice; pNew->bcdUSB = pCur->bcdUSB; pNew->bDeviceClass = pCur->bDeviceClass; pNew->bDeviceSubClass = pCur->bDeviceSubClass; pNew->bDeviceProtocol = pCur->bDeviceProtocol; pNew->bNumConfigurations = pCur->bNumConfigurations; pNew->enmState = pCur->enmState; pNew->u64SerialHash = pCur->u64SerialHash; pNew->bBus = pCur->bBus; pNew->bPort = pCur->bPort; pNew->enmSpeed = pCur->enmSpeed; /* link it */ pNew->pNext = NULL; pNew->pPrev = *ppNext; *ppNext = pNew; ppNext = &pNew->pNext; } pCur = pCur->pNext; } RTSemFastMutexRelease(m->hMtxDevices); return pFirst; }
VBOXDDU_DECL(int) VDDbgIoLogComplete(VDIOLOGGER hIoLogger, VDIOLOGENT hIoLogEntry, int rcReq, PCRTSGBUF pSgBuf) { int rc = VINF_SUCCESS; PVDIOLOGGERINT pIoLogger = hIoLogger; PVDIOLOGENTINT pIoLogEntry = hIoLogEntry; AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE); AssertPtrReturn(pIoLogEntry, VERR_INVALID_HANDLE); rc = RTSemFastMutexRequest(pIoLogger->hMtx); AssertRCReturn(rc, rc); IoLogEntryComplete Entry; Entry.u32Type = VDIOLOG_EVENT_COMPLETE; Entry.u64Id = RT_H2LE_U64(pIoLogEntry->idStart); Entry.msDuration = RTTimeProgramMilliTS() - RT_H2LE_U64(pIoLogEntry->tsStart); Entry.i32Rc = (int32_t)RT_H2LE_U32((uint32_t)rcReq); Entry.u64IoBuffer = RT_H2LE_U64(pIoLogEntry->cbIo); /* Write new entry. */ rc = RTFileWriteAt(pIoLogger->hFile, pIoLogger->offWriteNext, &Entry, sizeof(Entry), NULL); if (RT_SUCCESS(rc)) { pIoLogger->offWriteNext += sizeof(Entry); if (pIoLogEntry->cbIo) { rc = vddbgIoLogWriteSgBuf(pIoLogger, pIoLogger->offWriteNext, pSgBuf, pIoLogEntry->cbIo); if (RT_SUCCESS(rc)) pIoLogger->offWriteNext += pIoLogEntry->cbIo; else { pIoLogger->offWriteNext -= sizeof(Entry); rc = RTFileSetSize(pIoLogger->hFile, pIoLogger->offWriteNext); } } } RTMemCacheFree(pIoLogger->hMemCacheIoLogEntries, pIoLogEntry); RTSemFastMutexRelease(pIoLogger->hMtx); return rc; }
/** * Detach entry point, to detach a device to the system or suspend it. * * @param pDip The module structure instance. * @param enmCmd Operation type (detach/suspend). * * @return corresponding solaris error code. */ static int VBoxDrvSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd) { LogFlowFunc(("VBoxDrvSolarisDetach\n")); switch (enmCmd) { case DDI_DETACH: { #ifndef USE_SESSION_HASH ddi_remove_minor_node(pDip, NULL); #else int instance = ddi_get_instance(pDip); vbox_devstate_t *pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, instance); ddi_remove_minor_node(pDip, NULL); ddi_soft_state_free(g_pVBoxDrvSolarisState, instance); #endif ddi_prop_remove_all(pDip); return DDI_SUCCESS; } case DDI_SUSPEND: { #if 0 RTSemFastMutexRequest(g_DevExt.mtxGip); if (g_DevExt.pGipTimer && g_DevExt.cGipUsers > 0) RTTimerStop(g_DevExt.pGipTimer); RTSemFastMutexRelease(g_DevExt.mtxGip); #endif RTPowerSignalEvent(RTPOWEREVENT_SUSPEND); LogFlow(("vboxdrv: Falling to suspend mode.\n")); return DDI_SUCCESS; } default: return DDI_FAILURE; } }
void renderspu_SystemSwapBuffers(WindowInfo *window, GLint flags) { CRASSERT(window); CRASSERT(window->window); ContextInfo *context = renderspuGetWindowContext(window); if(!context) crError("Render SPU (renderspu_SystemSwapBuffers): SwapBuffers got a null context from the window"); RTSemFastMutexRequest(render_spu.syncMutex); // DEBUG_MSG_POETZSCH (("Swapped %d context %x visible: %d\n", window->BltInfo.Base.id, context->context, IsWindowVisible (window->window))); if (context->visual && context->visual->visAttribs & CR_DOUBLE_BIT) render_spu.ws.aglSwapBuffers(context->context); else glFlush(); RTSemFastMutexRelease(render_spu.syncMutex); /* This method seems called very often. To prevent the dock using all free * resources we update the dock only two times per second. */ uint64_t curTS = RTTimeMilliTS(); if ((curTS - render_spu.uiDockUpdateTS) > 500) { OSStatus status = noErr; /* Send a event to the main thread, cause some function of Carbon aren't * thread safe */ EventRef evt; status = CreateEvent(NULL, kEventClassVBox, kEventVBoxUpdateDock, 0, kEventAttributeNone, &evt); CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU (renderspu_SystemSwapBuffers): CreateEvent Failed"); status = PostEventToQueue(GetMainEventQueue(), evt, kEventPriorityStandard); CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU (renderspu_SystemSwapBuffers): PostEventToQueue Failed"); render_spu.uiDockUpdateTS = curTS; } }
VBOXDDU_DECL(int) VDDbgIoLogStart(VDIOLOGGER hIoLogger, bool fAsync, VDDBGIOLOGREQ enmTxDir, uint64_t off, size_t cbIo, PCRTSGBUF pSgBuf, PVDIOLOGENT phIoLogEntry) { int rc = VINF_SUCCESS; PVDIOLOGGERINT pIoLogger = hIoLogger; PVDIOLOGENTINT pIoLogEntry = NULL; AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE); AssertPtrReturn(phIoLogEntry, VERR_INVALID_POINTER); AssertReturn(enmTxDir > VDDBGIOLOGREQ_INVALID && enmTxDir <= VDDBGIOLOGREQ_FLUSH, VERR_INVALID_PARAMETER); rc = RTSemFastMutexRequest(pIoLogger->hMtx); AssertRCReturn(rc, rc); pIoLogEntry = (PVDIOLOGENTINT)RTMemCacheAlloc(pIoLogger->hMemCacheIoLogEntries); if (pIoLogEntry) { IoLogEntryStart Entry; pIoLogEntry->idStart = pIoLogger->idNext++; Entry.u32Type = VDIOLOG_EVENT_START; Entry.u8AsyncIo = fAsync ? 1 : 0; Entry.u32ReqType = enmTxDir; Entry.u64Id = RT_H2LE_U64(pIoLogEntry->idStart); Entry.Io.u64Off = RT_H2LE_U64(off); Entry.Io.u64IoSize = RT_H2LE_U64(cbIo); /* Write new entry. */ rc = RTFileWriteAt(pIoLogger->hFile, pIoLogger->offWriteNext, &Entry, sizeof(Entry), NULL); if (RT_SUCCESS(rc)) { pIoLogger->offWriteNext += sizeof(Entry); if ( enmTxDir == VDDBGIOLOGREQ_WRITE && (pIoLogger->fFlags & VDDBG_IOLOG_LOG_DATA_WRITTEN)) { /* Write data. */ rc = vddbgIoLogWriteSgBuf(pIoLogger, pIoLogger->offWriteNext, pSgBuf, cbIo); if (RT_FAILURE(rc)) { pIoLogger->offWriteNext -= sizeof(Entry); rc = RTFileSetSize(pIoLogger->hFile, pIoLogger->offWriteNext); } else pIoLogger->offWriteNext += cbIo; } } if (RT_SUCCESS(rc)) { pIoLogEntry->tsStart = RTTimeProgramMilliTS(); if ( enmTxDir == VDDBGIOLOGREQ_READ && (pIoLogger->fFlags & VDDBG_IOLOG_LOG_DATA_READ)) pIoLogEntry->cbIo = cbIo; else pIoLogEntry->cbIo = 0; *phIoLogEntry = pIoLogEntry; } else { pIoLogger->idNext--; RTMemCacheFree(pIoLogger->hMemCacheIoLogEntries, pIoLogEntry); } } else rc = VERR_NO_MEMORY; RTSemFastMutexRelease(pIoLogger->hMtx); return rc; }
/** * Attach entry point, to attach a device to the system or resume it. * * @param pDip The module structure instance. * @param enmCmd Operation type (attach/resume). * * @return corresponding solaris error code. */ static int VBoxDrvSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd) { LogFlowFunc(("VBoxDrvSolarisAttach\n")); switch (enmCmd) { case DDI_ATTACH: { int rc; #ifdef USE_SESSION_HASH int instance = ddi_get_instance(pDip); vbox_devstate_t *pState; if (ddi_soft_state_zalloc(g_pVBoxDrvSolarisState, instance) != DDI_SUCCESS) { LogRel(("VBoxDrvSolarisAttach: state alloc failed\n")); return DDI_FAILURE; } pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, instance); #endif /* * Register for suspend/resume notifications */ rc = ddi_prop_create(DDI_DEV_T_NONE, pDip, DDI_PROP_CANSLEEP /* kmem alloc can sleep */, "pm-hardware-state", "needs-suspend-resume", sizeof("needs-suspend-resume")); if (rc != DDI_PROP_SUCCESS) LogRel(("vboxdrv: Suspend/Resume notification registration failed.\n")); /* * Register ourselves as a character device, pseudo-driver */ #ifdef VBOX_WITH_HARDENING rc = ddi_create_priv_minor_node(pDip, DEVICE_NAME_SYS, S_IFCHR, 0 /*minor*/, DDI_PSEUDO, 0, NULL, NULL, 0600); #else rc = ddi_create_priv_minor_node(pDip, DEVICE_NAME_SYS, S_IFCHR, 0 /*minor*/, DDI_PSEUDO, 0, "none", "none", 0666); #endif if (rc == DDI_SUCCESS) { rc = ddi_create_priv_minor_node(pDip, DEVICE_NAME_USR, S_IFCHR, 1 /*minor*/, DDI_PSEUDO, 0, "none", "none", 0666); if (rc == DDI_SUCCESS) { #ifdef USE_SESSION_HASH pState->pDip = pDip; #endif ddi_report_dev(pDip); return DDI_SUCCESS; } ddi_remove_minor_node(pDip, NULL); } return DDI_FAILURE; } case DDI_RESUME: { #if 0 RTSemFastMutexRequest(g_DevExt.mtxGip); if (g_DevExt.pGipTimer) RTTimerStart(g_DevExt.pGipTimer, 0); RTSemFastMutexRelease(g_DevExt.mtxGip); #endif RTPowerSignalEvent(RTPOWEREVENT_RESUME); LogFlow(("vboxdrv: Awakened from suspend.\n")); return DDI_SUCCESS; } default: return DDI_FAILURE; } return DDI_FAILURE; }
/* Window event handler */ pascal OSStatus windowEvtHndlr(EventHandlerCallRef myHandler, EventRef event, void* userData) { WindowRef window = NULL; OSStatus eventResult = eventNotHandledErr; UInt32 class = GetEventClass (event); UInt32 kind = GetEventKind (event); /* If we aren't initialized or even deinitialized already (as on VM * shutdown) do nothing. */ if (!render_spu.fInit) return eventNotHandledErr; /* Fetch the sender of the event */ GetEventParameter(event, kEventParamDirectObject, typeWindowRef, NULL, sizeof(WindowRef), NULL, &window); switch (class) { case kEventClassVBox: { switch (kind) { case kEventVBoxUpdateContext: { #ifndef __LP64__ /** @todo port to 64-bit darwin! Need to check if this event is generated or not (it probably isn't). */ WindowInfo *wi1; GetEventParameter(event, kEventParamUserData, typeVoidPtr, NULL, sizeof(wi1), NULL, &wi1); ContextInfo *context = renderspuGetWindowContext(wi1); if (context && context->context) { AGLContext tmpContext = render_spu.ws.aglGetCurrentContext(); DEBUG_MSG_POETZSCH (("kEventVBoxUpdateContext %x %x\n", wi1, context->context)); RTSemFastMutexRequest(render_spu.syncMutex); GLboolean result = render_spu.ws.aglSetCurrentContext(context->context); if (result) { result = render_spu.ws.aglUpdateContext(context->context); CHECK_AGL_RC (result, "Render SPU (windowEvtHndlr): UpdateContext Failed"); renderspu_SystemWindowApplyVisibleRegion(wi1); /* Reapply the last active context */ if (tmpContext) { result = render_spu.ws.aglSetCurrentContext(tmpContext); CHECK_AGL_RC (result, "Render SPU (windowEvtHndlr): SetCurrentContext Failed"); if (result) { result = render_spu.ws.aglUpdateContext(tmpContext); CHECK_AGL_RC (result, "Render SPU (windowEvtHndlr): UpdateContext Failed"); } } } RTSemFastMutexRelease(render_spu.syncMutex); } eventResult = noErr; #endif break; } case kEventVBoxBoundsChanged: { #ifndef __LP64__ /** @todo port to 64-bit darwin! Need to check if this event is generated or not (it probably isn't). */ HIPoint p; GetEventParameter(event, kEventParamOrigin, typeHIPoint, NULL, sizeof(p), NULL, &p); HISize s; GetEventParameter(event, kEventParamDimensions, typeHISize, NULL, sizeof(s), NULL, &s); HIRect r = CGRectMake (0, 0, s.width, s.height); DEBUG_MSG_POETZSCH (("kEventVBoxBoundsChanged %f %f %f %f\n", p.x, p.y, s.width, s.height)); GLint l[4] = { 0, 0, r.size.width, r.size.height }; /* Update the root window clip region */ renderspu_SystemSetRootVisibleRegion(1, l); /* Temporary save the current active context */ AGLContext tmpContext = render_spu.ws.aglGetCurrentContext(); crHashtableWalk(render_spu.windowTable, crClipRootHelper, NULL); /* Reapply the last active context */ if (tmpContext) { RTSemFastMutexRequest(render_spu.syncMutex); GLboolean result = render_spu.ws.aglSetCurrentContext(tmpContext); CHECK_AGL_RC (result, "Render SPU (windowEvtHndlr): SetCurrentContext Failed"); /* Doesn't work with DirectX; Anyway doesn't */ /* if (result)*/ /* {*/ /* result = render_spu.ws.aglUpdateContext(tmpContext);*/ /* CHECK_AGL_RC (result, "Render SPU (windowEvtHndlr): UpdateContext Failed");*/ /* }*/ RTSemFastMutexRelease(render_spu.syncMutex); } eventResult = noErr; #endif break; } }; break; } break; }; return eventResult; }
GLboolean renderspuWindowAttachContext(WindowInfo *wi, WindowRef window, ContextInfo *context) { GLboolean result; if(!context || !wi) return render_spu.ws.aglSetCurrentContext( NULL ); /* DEBUG_MSG_POETZSCH (("WindowAttachContext %d\n", wi->BltInfo.Base.id));*/ /* Flush old context first */ if (context->currentWindow->window != window) render_spu.self.Flush(); /* If the window buffer name is uninitialized we have to create a new * dummy context. */ if (wi->bufferName == -1) { DEBUG_MSG_POETZSCH (("WindowAttachContext: create context %d\n", wi->BltInfo.Base.id)); /* Use the same visual bits as those in the context structure */ AGLPixelFormat pix; if( !renderspuChoosePixelFormat(context, &pix) ) { crError( "Render SPU (renderspuWindowAttachContext): Unable to create pixel format" ); return GL_FALSE; } /* Create the dummy context */ wi->dummyContext = render_spu.ws.aglCreateContext( pix, NULL ); renderspuDestroyPixelFormat( context, &pix ); if( !wi->dummyContext ) { crError( "Render SPU (renderspuWindowAttachContext): Could not create rendering context" ); return GL_FALSE; } AGLDrawable drawable; #ifdef __LP64__ /** @todo port to 64-bit darwin. */ drawable = NULL; #else drawable = (AGLDrawable) GetWindowPort(window); #endif /* New global buffer name */ wi->bufferName = render_spu.currentBufferName++; /* Set the new buffer name to the dummy context. This enable the * sharing of the same hardware buffer afterwards. */ result = render_spu.ws.aglSetInteger(wi->dummyContext, AGL_BUFFER_NAME, &wi->bufferName); CHECK_AGL_RC (result, "Render SPU (renderspuWindowAttachContext): SetInteger Failed"); /* Assign the dummy context to the window */ result = render_spu.ws.aglSetDrawable(wi->dummyContext, drawable); CHECK_AGL_RC (result, "Render SPU (renderspuWindowAttachContext): SetDrawable Failed"); } AGLDrawable oldDrawable; AGLDrawable newDrawable; oldDrawable = render_spu.ws.aglGetDrawable(context->context); #ifdef __LP64__ /** @todo port to 64-bit darwin. */ newDrawable = oldDrawable; #else newDrawable = (AGLDrawable) GetWindowPort(window); #endif RTSemFastMutexRequest(render_spu.syncMutex); /* Only switch the context if the drawable has changed */ if (oldDrawable != newDrawable) { /* Reset the current context */ result = render_spu.ws.aglSetDrawable(context->context, NULL); CHECK_AGL_RC (result, "Render SPU (renderspuWindowAttachContext): SetDrawable Failed"); /* Set the buffer name of the dummy context to the current context * also. After that both share the same hardware buffer. */ render_spu.ws.aglSetInteger (context->context, AGL_BUFFER_NAME, &wi->bufferName); CHECK_AGL_RC (result, "Render SPU (renderspuWindowAttachContext): SetInteger Failed"); /* Set the new drawable */ #ifdef __LP64__ /** @todo port to 64-bit darwin. */ result = -1; #else result = render_spu.ws.aglSetDrawable(context->context, newDrawable); #endif CHECK_AGL_RC (result, "Render SPU (renderspuWindowAttachContext): SetDrawable Failed"); renderspuSetWindowContext(window, context); } result = render_spu.ws.aglSetCurrentContext(context->context); CHECK_AGL_RC (result, "Render SPU (renderspuWindowAttachContext): SetCurrentContext Failed"); result = render_spu.ws.aglUpdateContext(context->context); CHECK_AGL_RC (result, "Render SPU (renderspuWindowAttachContext): UpdateContext Failed"); RTSemFastMutexRelease(render_spu.syncMutex); return result; }
VBOXDDU_DECL(int) VDDbgIoLogEventGetStartDiscard(VDIOLOGGER hIoLogger, uint64_t *pidEvent, bool *pfAsync, PRTRANGE *ppaRanges, unsigned *pcRanges) { int rc = VINF_SUCCESS; PVDIOLOGGERINT pIoLogger = hIoLogger; AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE); AssertPtrReturn(pidEvent, VERR_INVALID_POINTER); AssertPtrReturn(pfAsync, VERR_INVALID_POINTER); rc = RTSemFastMutexRequest(pIoLogger->hMtx); AssertRCReturn(rc, rc); if ( pIoLogger->u32EventTypeNext == VDIOLOG_EVENT_START && pIoLogger->enmReqTypeNext == VDDBGIOLOGREQ_DISCARD) { IoLogEntryStart Entry; rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext, &Entry, sizeof(Entry), NULL); if (RT_SUCCESS(rc)) { PRTRANGE paRanges = NULL; IoLogEntryDiscard DiscardRange; pIoLogger->offReadNext += sizeof(Entry); *pfAsync = RT_BOOL(Entry.u8AsyncIo); *pidEvent = RT_LE2H_U64(Entry.u64Id); *pcRanges = RT_LE2H_U32(Entry.Discard.cRanges); paRanges = (PRTRANGE)RTMemAllocZ(*pcRanges * sizeof(RTRANGE)); if (paRanges) { for (unsigned i = 0; i < *pcRanges; i++) { rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext + i*sizeof(DiscardRange), &DiscardRange, sizeof(DiscardRange), NULL); if (RT_FAILURE(rc)) break; paRanges[i].offStart = RT_LE2H_U64(DiscardRange.u64Off); paRanges[i].cbRange = RT_LE2H_U32(DiscardRange.u32Discard); } if (RT_SUCCESS(rc)) { pIoLogger->offReadNext += *pcRanges * sizeof(DiscardRange); *ppaRanges = paRanges; } else { pIoLogger->offReadNext -= sizeof(Entry); RTMemFree(paRanges); } } else rc = VERR_NO_MEMORY; } } else rc = VERR_INVALID_STATE; if (RT_SUCCESS(rc)) pIoLogger->u32EventTypeNext = 0; RTSemFastMutexRelease(pIoLogger->hMtx); return rc; }
int USBProxyBackendUsbIp::wait(RTMSINTERVAL aMillies) { int rc = VINF_SUCCESS; bool fDeviceListChangedOrWokenUp = false; /* Try to reconnect once when we enter if we lost the connection earlier. */ if (m->hSocket == NIL_RTSOCKET) rc = reconnect(); /* Query a new device list upon entering. */ if (m->enmRecvState == kUsbIpRecvState_None) { rc = startListExportedDevicesReq(); if (RT_FAILURE(rc)) disconnect(); } /* * Because the USB/IP protocol doesn't specify a way to get notified about * new or removed exported devices we have to poll the host periodically for * a new device list and compare it with the previous one notifying the proxy * service about changes. */ while ( !fDeviceListChangedOrWokenUp && (aMillies == RT_INDEFINITE_WAIT || aMillies > 0) && RT_SUCCESS(rc)) { RTMSINTERVAL msWait = aMillies; uint64_t msPollStart = RTTimeMilliTS(); uint32_t uIdReady = 0; uint32_t fEventsRecv = 0; /* Limit the waiting time to 1sec so we can either reconnect or get a new device list. */ if (m->hSocket == NIL_RTSOCKET || m->enmRecvState == kUsbIpRecvState_None) msWait = RT_MIN(1000, aMillies); rc = RTPoll(m->hPollSet, msWait, &fEventsRecv, &uIdReady); if (RT_SUCCESS(rc)) { if (uIdReady == USBIP_POLL_ID_PIPE) { /* Drain the wakeup pipe. */ char bRead = 0; size_t cbRead = 0; rc = RTPipeRead(m->hWakeupPipeR, &bRead, 1, &cbRead); Assert(RT_SUCCESS(rc) && cbRead == 1); fDeviceListChangedOrWokenUp = true; } else if (uIdReady == USBIP_POLL_ID_SOCKET) { if (fEventsRecv & RTPOLL_EVT_ERROR) rc = VERR_NET_SHUTDOWN; else rc = receiveData(); if (RT_SUCCESS(rc)) { /* * If we are in the none state again we received the previous request * and have a new device list to compare the old against. */ if (m->enmRecvState == kUsbIpRecvState_None) { if (hasDevListChanged(m->pHead)) fDeviceListChangedOrWokenUp = true; /* Update to the new list in any case now that we have it anyway. */ RTSemFastMutexRequest(m->hMtxDevices); freeDeviceList(m->pUsbDevicesCur); m->cUsbDevicesCur = m->cDevicesCur; m->pUsbDevicesCur = m->pHead; RTSemFastMutexRelease(m->hMtxDevices); m->pHead = NULL; resetRecvState(); } } else if (rc == VERR_NET_SHUTDOWN || rc == VERR_BROKEN_PIPE) { LogRelMax(10, ("USB/IP: Lost connection to host \"%s\", trying to reconnect...\n", m->pszHost)); disconnect(); rc = VINF_SUCCESS; } } else { AssertMsgFailed(("Invalid poll ID returned\n")); rc = VERR_INVALID_STATE; } aMillies -= (RTTimeMilliTS() - msPollStart); } else if (rc == VERR_TIMEOUT) { aMillies -= msWait; if (aMillies) { /* Try to reconnect and start a new request if we lost the connection before. */ if (m->hSocket == NIL_RTSOCKET) rc = reconnect(); if (RT_SUCCESS(rc)) rc = startListExportedDevicesReq(); } } } return rc; }
DECLINLINE(int) vboxPciVmLock(PVBOXRAWPCIDRVVM pThis) { int rc = RTSemFastMutexRequest(pThis->hFastMtx); AssertRC(rc); return rc; }
DECLINLINE(int) vboxPciGlobalsLock(PVBOXRAWPCIGLOBALS pGlobals) { int rc = RTSemFastMutexRequest(pGlobals->hFastMtx); AssertRC(rc); return rc; }
VBOXDDU_DECL(int) VDDbgIoLogStartDiscard(VDIOLOGGER hIoLogger, bool fAsync, PCRTRANGE paRanges, unsigned cRanges, PVDIOLOGENT phIoLogEntry) { int rc = VINF_SUCCESS; PVDIOLOGGERINT pIoLogger = hIoLogger; PVDIOLOGENTINT pIoLogEntry = NULL; AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE); AssertPtrReturn(phIoLogEntry, VERR_INVALID_POINTER); rc = RTSemFastMutexRequest(pIoLogger->hMtx); AssertRCReturn(rc, rc); pIoLogEntry = (PVDIOLOGENTINT)RTMemCacheAlloc(pIoLogger->hMemCacheIoLogEntries); if (pIoLogEntry) { IoLogEntryStart Entry; pIoLogEntry->idStart = pIoLogger->idNext++; Entry.u32Type = VDIOLOG_EVENT_START; Entry.u8AsyncIo = fAsync ? 1 : 0; Entry.u32ReqType = VDDBGIOLOGREQ_DISCARD; Entry.u64Id = RT_H2LE_U64(pIoLogEntry->idStart); Entry.Discard.cRanges = RT_H2LE_U32(cRanges); /* Write new entry. */ rc = RTFileWriteAt(pIoLogger->hFile, pIoLogger->offWriteNext, &Entry, sizeof(Entry), NULL); if (RT_SUCCESS(rc)) { pIoLogger->offWriteNext += sizeof(Entry); IoLogEntryDiscard DiscardRange; for (unsigned i = 0; i < cRanges; i++) { DiscardRange.u64Off = RT_H2LE_U64(paRanges[i].offStart); DiscardRange.u32Discard = RT_H2LE_U32((uint32_t)paRanges[i].cbRange); rc = RTFileWriteAt(pIoLogger->hFile, pIoLogger->offWriteNext + i*sizeof(DiscardRange), &DiscardRange, sizeof(DiscardRange), NULL); if (RT_FAILURE(rc)) break; } if (RT_FAILURE(rc)) { pIoLogger->offWriteNext -= sizeof(Entry); rc = RTFileSetSize(pIoLogger->hFile, pIoLogger->offWriteNext); } else pIoLogger->offWriteNext += cRanges * sizeof(DiscardRange); } if (RT_SUCCESS(rc)) { pIoLogEntry->tsStart = RTTimeProgramMilliTS(); pIoLogEntry->cbIo = 0; *phIoLogEntry = pIoLogEntry; } else { pIoLogger->idNext--; RTMemCacheFree(pIoLogger->hMemCacheIoLogEntries, pIoLogEntry); } } else rc = VERR_NO_MEMORY; RTSemFastMutexRelease(pIoLogger->hMtx); return rc; }
/** * Records an VUSB event. * * @returns VBox status code. * @param hSniffer The sniffer instance. * @param pUrb The URB triggering the event. * @param enmEvent The type of event to record. */ DECLHIDDEN(int) VUSBSnifferRecordEvent(VUSBSNIFFER hSniffer, PVUSBURB pUrb, VUSBSNIFFEREVENT enmEvent) { int rc = VINF_SUCCESS; PVUSBSNIFFERINT pThis = hSniffer; DumpFileEpb Epb; DumpFileUsbHeaderLnxMmapped UsbHdr; DumpFileUsbSetup UsbSetup; RTTIMESPEC TimeNow; uint64_t u64TimestampEvent; size_t cbUrbLength = 0; uint32_t cbDataLength = 0; uint32_t cbCapturedLength = sizeof(UsbHdr); uint32_t cIsocPkts = 0; uint8_t *pbData = NULL; RTTimeNow(&TimeNow); u64TimestampEvent = RTTimeSpecGetNano(&TimeNow); /* Start with the enhanced packet block. */ Epb.Hdr.u32BlockType = DUMPFILE_EPB_BLOCK_TYPE; Epb.Hdr.u32BlockTotalLength = 0; Epb.u32InterfaceId = 0; Epb.u32TimestampHigh = (u64TimestampEvent >> 32) & UINT32_C(0xffffffff); Epb.u32TimestampLow = u64TimestampEvent & UINT32_C(0xffffffff); UsbHdr.u64Id = (uint64_t)pUrb; /** @todo: check whether the pointer is a good ID. */ switch (enmEvent) { case VUSBSNIFFEREVENT_SUBMIT: UsbHdr.u8EventType = DUMPFILE_USB_EVENT_TYPE_SUBMIT; cbUrbLength = pUrb->cbData; break; case VUSBSNIFFEREVENT_COMPLETE: UsbHdr.u8EventType = DUMPFILE_USB_EVENT_TYPE_COMPLETE; cbUrbLength = pUrb->cbData; break; case VUSBSNIFFEREVENT_ERROR_SUBMIT: case VUSBSNIFFEREVENT_ERROR_COMPLETE: UsbHdr.u8EventType = DUMPFILE_USB_EVENT_TYPE_ERROR; break; default: AssertMsgFailed(("Invalid event type %d\n", enmEvent)); } cbDataLength = cbUrbLength; pbData = &pUrb->abData[0]; switch (pUrb->enmType) { case VUSBXFERTYPE_ISOC: { int32_t i32ErrorCount = 0; UsbHdr.u8TransferType = 0; cIsocPkts = pUrb->cIsocPkts; for (unsigned i = 0; i < cIsocPkts; i++) if ( pUrb->aIsocPkts[i].enmStatus != VUSBSTATUS_OK && pUrb->aIsocPkts[i].enmStatus != VUSBSTATUS_NOT_ACCESSED) i32ErrorCount++; UsbHdr.u.IsoRec.i32ErrorCount = i32ErrorCount; UsbHdr.u.IsoRec.i32NumDesc = pUrb->cIsocPkts; cbCapturedLength += cIsocPkts * sizeof(DumpFileUsbIsoDesc); break; } case VUSBXFERTYPE_BULK: UsbHdr.u8TransferType = 3; break; case VUSBXFERTYPE_INTR: UsbHdr.u8TransferType = 1; break; case VUSBXFERTYPE_CTRL: case VUSBXFERTYPE_MSG: UsbHdr.u8TransferType = 2; break; default: AssertMsgFailed(("invalid transfer type %d\n", pUrb->enmType)); } if (pUrb->enmDir == VUSBDIRECTION_IN) { if (enmEvent == VUSBSNIFFEREVENT_SUBMIT) cbDataLength = 0; } else if (pUrb->enmDir == VUSBDIRECTION_OUT) { if ( enmEvent == VUSBSNIFFEREVENT_COMPLETE || pUrb->enmType == VUSBXFERTYPE_CTRL || pUrb->enmType == VUSBXFERTYPE_MSG) cbDataLength = 0; } else if (pUrb->enmDir == VUSBDIRECTION_SETUP) cbDataLength -= sizeof(VUSBSETUP); Epb.u32CapturedLen = cbCapturedLength + cbDataLength; Epb.u32PacketLen = cbCapturedLength + cbUrbLength; UsbHdr.u8EndpointNumber = pUrb->EndPt | (pUrb->enmDir == VUSBDIRECTION_IN ? 0x80 : 0x00); UsbHdr.u8DeviceAddress = pUrb->DstAddress; UsbHdr.u16BusId = 0; UsbHdr.u8DataFlag = cbDataLength ? 0 : 1; UsbHdr.u64TimestampSec = u64TimestampEvent / RT_NS_1SEC_64; UsbHdr.u32TimestampUSec = u64TimestampEvent / RT_NS_1US_64 - UsbHdr.u64TimestampSec * RT_US_1SEC; UsbHdr.i32Status = pUrb->enmStatus; UsbHdr.u32UrbLength = cbUrbLength; UsbHdr.u32DataLength = cbDataLength + cIsocPkts * sizeof(DumpFileUsbIsoDesc); UsbHdr.i32Interval = 0; UsbHdr.i32StartFrame = 0; UsbHdr.u32XferFlags = 0; UsbHdr.u32NumDesc = cIsocPkts; if ( (pUrb->enmType == VUSBXFERTYPE_MSG || pUrb->enmType == VUSBXFERTYPE_CTRL) && enmEvent == VUSBSNIFFEREVENT_SUBMIT) { PVUSBSETUP pSetup = (PVUSBSETUP)pUrb->abData; UsbHdr.u.UsbSetup.bmRequestType = pSetup->bmRequestType; UsbHdr.u.UsbSetup.bRequest = pSetup->bRequest; UsbHdr.u.UsbSetup.wValue = pSetup->wValue; UsbHdr.u.UsbSetup.wIndex = pSetup->wIndex; UsbHdr.u.UsbSetup.wLength = pSetup->wLength; UsbHdr.u8SetupFlag = 0; } else UsbHdr.u8SetupFlag = '-'; /* Follow usbmon source here. */ /* Write the packet to the capture file. */ rc = RTSemFastMutexRequest(pThis->hMtx); if (RT_SUCCESS(rc)) { rc = vusbSnifferBlockNew(pThis, &Epb.Hdr, sizeof(Epb)); if (RT_SUCCESS(rc)) rc = vusbSnifferBlockAddData(pThis, &UsbHdr, sizeof(UsbHdr)); /* Add Isochronous descriptors now. */ for (unsigned i = 0; i < cIsocPkts && RT_SUCCESS(rc); i++) { DumpFileUsbIsoDesc IsoDesc; IsoDesc.i32Status = pUrb->aIsocPkts[i].enmStatus; IsoDesc.u32Offset = pUrb->aIsocPkts[i].off; IsoDesc.u32Len = pUrb->aIsocPkts[i].cb; rc = vusbSnifferBlockAddData(pThis, &IsoDesc, sizeof(IsoDesc)); } /* Record data. */ if ( RT_SUCCESS(rc) && cbDataLength) rc = vusbSnifferBlockAddData(pThis, pbData, cbDataLength); if (RT_SUCCESS(rc)) rc = vusbSnifferAddOption(pThis, DUMPFILE_OPTION_CODE_END, NULL, 0); if (RT_SUCCESS(rc)) rc = vusbSnifferBlockCommit(pThis); RTSemFastMutexRelease(pThis->hMtx); } return rc; }