//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtuEventsSetEvent -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- // static DtStatus DtuEventsSetEvent( DtuEvents* pDtuEvents, UInt EventType, UInt Value1, UInt Value2) { DtuEvent* pDtuEvent; // Skip unregistered events if ((EventType & pDtuEvents->m_EventTypeMask) != 0) { DtSpinLockAcquire(&pDtuEvents->m_Lock); if (EventType == DTU_EVENT_TYPE_IOCONFIG) { UInt i; for (i=0; i<pDtuEvents->m_NumPendingEvents; i++) { if (pDtuEvents->m_PendingEvents[i].m_EventType==DTU_EVENT_TYPE_IOCONFIG && pDtuEvents->m_PendingEvents[i].m_EventValue1==Value1) { // Event is already pending, don't create a duplicate DtSpinLockRelease(&pDtuEvents->m_Lock); return DT_STATUS_OK; } } } // Add new events if (pDtuEvents->m_NumPendingEvents == MAX_PENDING_EVENTS) { // Remove oldest event DtDbgOut(AVG, EVENTS, "Max. number of events. Remove old event"); DtMemMove(&pDtuEvents->m_PendingEvents[0], &pDtuEvents->m_PendingEvents[1], sizeof(DtuEvent) * (MAX_PENDING_EVENTS - 1)); pDtuEvent = &pDtuEvents->m_PendingEvents[MAX_PENDING_EVENTS - 1]; } else { pDtuEvent = &pDtuEvents->m_PendingEvents[pDtuEvents->m_NumPendingEvents]; pDtuEvents->m_NumPendingEvents++; } DtDbgOut(MAX, EVENTS, "New event #%d. Type: %d, Value1: %d, Value2: %d", pDtuEvents->m_NumPendingEvents, EventType, Value1, Value2); pDtuEvent->m_EventType = EventType; pDtuEvent->m_EventValue1 = Value1; pDtuEvent->m_EventValue2 = Value2; // Trigger wait function if it was waiting DtEventSet(&pDtuEvents->m_PendingEvent); DtSpinLockRelease(&pDtuEvents->m_Lock); } return DT_STATUS_OK; }
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaEventsSetEvent -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- // static DtStatus DtaEventsSetEvent( DtaEvents* pDtaEvents, UInt EventType, UInt Value1, UInt Value2) { DtStatus Result = DT_STATUS_OK; DtaEvent* pDtaEvent; // Skip unregistered events if ((EventType & pDtaEvents->m_EventTypeMask) != 0) { DtSpinLockAcquire(&pDtaEvents->m_Lock); // Add new events if (pDtaEvents->m_NumPendingEvents == MAX_PENDING_EVENTS) { // Remove oldest event DtDbgOut(AVG, EVENTS, "Max. number of events. Remove old event"); DtMemMove(&pDtaEvents->m_PendingEvents[0], &pDtaEvents->m_PendingEvents[1], sizeof(DtaEvent) * (MAX_PENDING_EVENTS - 1)); pDtaEvent = &pDtaEvents->m_PendingEvents[MAX_PENDING_EVENTS - 1]; } else { pDtaEvent = &pDtaEvents->m_PendingEvents[pDtaEvents->m_NumPendingEvents]; pDtaEvents->m_NumPendingEvents++; } DtDbgOut(MAX, EVENTS, "New event #%d. Type: %d, Value1: %d, Value2: %d", pDtaEvents->m_NumPendingEvents, EventType, Value1, Value2); pDtaEvent->m_EventType = EventType; pDtaEvent->m_EventValue1 = Value1; pDtaEvent->m_EventValue2 = Value2; // Trigger wait function if it was waiting DtEventSet(&pDtaEvents->m_PendingEvent); DtSpinLockRelease(&pDtaEvents->m_Lock); } return Result; }
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtuEventsGet -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- // // Return a pending event. This functions blocks if no events are pending. // DtStatus DtuEventsGet( DtuDeviceData* pDvcData, DtFileObject* pFile, UInt* pEventType, UInt* pValue1, UInt* pValue2, Bool Wait) { DtStatus Result = DT_STATUS_OK; DtuEvents* pDtuEvents; if (pFile==NULL || pEventType==NULL || pValue1==NULL || pValue2==NULL) return DT_STATUS_INVALID_PARAMETER; // Get corresponding events object pDtuEvents = DtuEventsGetEventsObject(pDvcData, pFile); if (pDtuEvents == NULL) Result = DT_STATUS_NOT_FOUND; if (DT_SUCCESS(Result)) { DtEventReset(&pDtuEvents->m_PendingEvent); if (Wait && pDtuEvents->m_NumPendingEvents==0 && !pDtuEvents->m_CancelInProgress) { DtDbgOut(MAX, EVENTS, "Waiting for event"); // Wait for event to be triggered DtEventWait(&pDtuEvents->m_PendingEvent, -1); } // The next request will be rejected by the IoCtl function, so we can reset // the Cancel state here. if (pDtuEvents->m_CancelInProgress) Result = DT_STATUS_CANCELLED; pDtuEvents->m_CancelInProgress = FALSE; DtSpinLockAcquire(&pDtuEvents->m_Lock); // Return pending events if (pDtuEvents->m_NumPendingEvents != 0) { *pEventType = pDtuEvents->m_PendingEvents[0].m_EventType; *pValue1 = pDtuEvents->m_PendingEvents[0].m_EventValue1; *pValue2 = pDtuEvents->m_PendingEvents[0].m_EventValue2; DtDbgOut(MAX, EVENTS, "Event #%d. Type: %d, Value1: %d, Value2: %d", pDtuEvents->m_NumPendingEvents, *pEventType, *pValue1, *pValue2); pDtuEvents->m_NumPendingEvents--; if (pDtuEvents->m_NumPendingEvents != 0) { // Remove the old event DtMemMove(&pDtuEvents->m_PendingEvents[0], &pDtuEvents->m_PendingEvents[1], sizeof(DtuEvent) * pDtuEvents->m_NumPendingEvents); } } else { *pEventType = 0; *pValue1 = 0; *pValue2 = 0; if (Result == DT_STATUS_OK) Result = DT_STATUS_REQUEUE; // No pending events DtDbgOut(MAX, EVENTS, "Event #%d. No event", pDtuEvents->m_NumPendingEvents); } DtSpinLockRelease(&pDtuEvents->m_Lock); // Decrement refcount DtuEventsUnrefEventsObject(pDvcData, pDtuEvents); } return Result; }