//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtuEventsGetEventsObject -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- // static DtuEvents* DtuEventsGetEventsObject( DtuDeviceData* pDvcData, DtFileObject* pFile) { Int i; DtuEvents* pDtuEvents = NULL; for (i=0; i<MAX_NUM_FILE_HANDLES; i++) { DtSpinLockAcquire(&pDvcData->m_Events[i].m_Lock); if (pDvcData->m_Events[i].m_RefCount > 0) { if (DtFileCompare(&pDvcData->m_Events[i].m_File, pFile)) { pDtuEvents = &pDvcData->m_Events[i]; // Increment refcount pDtuEvents->m_RefCount++; } } DtSpinLockRelease(&pDvcData->m_Events[i].m_Lock); if (pDtuEvents != NULL) break; } return pDtuEvents; }
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaEncD7ProExclusiveAccess -.-.-.-.-.-.-.-.-.-.-.-.-.-.-. // DtStatus DtaEnDecExclusiveAccess( DtaNonIpPort* pNonIpPort, DtFileObject* pFile, Int Cmd) { DtStatus Result = DT_STATUS_OK; DtaEnDecPort* pEnDec = &pNonIpPort->m_EnDec; DtSpinLockAcquire(&pEnDec->m_ExclAccessLock); if (Cmd == DTA_EXCLUSIVE_ACCESS_CMD_ACQUIRE) { if (!pEnDec->m_ExclAccess) { pEnDec->m_ExclAccess = TRUE; pEnDec->m_ExclAccessOwner = *pFile; } else Result = DT_STATUS_IN_USE; } else if (Cmd == DTA_EXCLUSIVE_ACCESS_CMD_RELEASE) { if (pEnDec->m_ExclAccess) { if (DtFileCompare(&pEnDec->m_ExclAccessOwner, pFile)) { pEnDec->m_ExclAccess = FALSE; } else Result = DT_STATUS_IN_USE; } } else if (Cmd == DTA_EXCLUSIVE_ACCESS_CMD_PROBE) { if (pEnDec->m_ExclAccess) Result = DT_STATUS_IN_USE; } else if (Cmd == DTA_EXCLUSIVE_ACCESS_CMD_CHECK) { if (!pNonIpPort->m_ExclAccess) Result = DT_STATUS_EXCL_ACCESS_REQD; else if (!DtFileCompare(&pEnDec->m_ExclAccessOwner, pFile)) Result = DT_STATUS_IN_USE; } else Result = DT_STATUS_NOT_SUPPORTED; DtSpinLockRelease(&pEnDec->m_ExclAccessLock); return Result; }
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaEventsUnregister -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. // void DtaEventsUnregister(DtaDeviceData* pDvcData, DtFileObject* pFile) { DtaEvents* pDtaEvents = NULL; DtSpinLockAcquire(&pDvcData->m_EventsSpinlock); pDtaEvents = pDvcData->m_pEvents; while (pDtaEvents != NULL) { if (DtFileCompare(&pDtaEvents->m_File, pFile)) break; pDtaEvents = pDtaEvents->m_pNext; } if (pDtaEvents == NULL) { DtSpinLockRelease(&pDvcData->m_EventsSpinlock); return; } // Remove events struct from linked list while holding the spinlock if (pDtaEvents->m_pPrev != NULL) pDtaEvents->m_pPrev->m_pNext = pDtaEvents->m_pNext; else pDvcData->m_pEvents = pDtaEvents->m_pNext; if (pDtaEvents->m_pNext != NULL) pDtaEvents->m_pNext->m_pPrev = pDtaEvents->m_pPrev; pDtaEvents->m_pPrev = NULL; pDtaEvents->m_pNext = NULL; DtSpinLockRelease(&pDvcData->m_EventsSpinlock); // Even if two threads call DtaEventsUnregister at the same time we'll only come here // once. We remove the DtaEvents object from the linked-list while holding the // spinlock, so the second thread won't find the object and return immediately. // Signal pending event (will remove object if event was pending) DtaEventsGetCancel(pDvcData, pFile); // Decrement refcount to free object as soon as it's no longer in use DtaEventsUnrefEventsObject(pDvcData, pDtaEvents); }
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaEnDecClose -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- // DtStatus DtaEnDecClose(DtaNonIpPort* pNonIpPort, DtFileObject* pFile) { DtaEnDecPort* pEnDec = &pNonIpPort->m_EnDec; DtSpinLockAcquire(&pEnDec->m_ExclAccessLock); if (!pEnDec->m_ExclAccess || !DtFileCompare(&pEnDec->m_ExclAccessOwner, pFile)) { DtSpinLockRelease(&pEnDec->m_ExclAccessLock); return DT_STATUS_OK; } if (pNonIpPort->m_pDvcData->m_DevInfo.m_TypeNumber == 2180 || pNonIpPort->m_pDvcData->m_DevInfo.m_TypeNumber == 2182) DtaEncD7ProUncleanDetach(pNonIpPort); pEnDec->m_ExclAccess = FALSE; DtSpinLockRelease(&pEnDec->m_ExclAccessLock); return DT_STATUS_OK; }
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaEventsGetEventsObject -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- // static DtaEvents* DtaEventsGetEventsObject( DtaDeviceData* pDvcData, DtFileObject* pFile) { DtaEvents* pDtaEvents = NULL; DtSpinLockAcquire(&pDvcData->m_EventsSpinlock); pDtaEvents = pDvcData->m_pEvents; while (pDtaEvents != NULL) { if (DtFileCompare(&pDtaEvents->m_File, pFile)) { // Increment refcount DtAtomicIncrement(&pDtaEvents->m_RefCount); break; } pDtaEvents = pDtaEvents->m_pNext; } DtSpinLockRelease(&pDvcData->m_EventsSpinlock); return pDtaEvents; }