VOID FxInterrupt::FlushQueuedDpcs( VOID ) { KeFlushQueuedDpcs(); }
NTSTATUS EventLogStart(PEVENT_LOG EventLog) { LARGE_INTEGER TimerDueTime; NTSTATUS Status; RtlZeroMemory(EventLog, sizeof(EVENT_LOG)); InitializeListHead(&EventLog->EventListHead); KeInitializeSpinLock(&EventLog->EventListLock); KeInitializeTimer(&EventLog->Timer); KeInitializeDpc(&EventLog->TimerDpc, EventLogTimerDpcRoutine, EventLog); SysWorkerInit(&EventLog->Worker); Status = SysWorkerStart(&EventLog->Worker); if (!NT_SUCCESS(Status)) { goto start_failed; } TimerDueTime.QuadPart = 0; KeSetTimerEx(&EventLog->Timer, TimerDueTime, 500, &EventLog->TimerDpc); return STATUS_SUCCESS; start_failed: EventLog->Stopping = 1; KeCancelTimer(&EventLog->Timer); KeFlushQueuedDpcs(); SysWorkerStop(&EventLog->Worker); EventLogFlush(EventLog); return Status; }
VOID NTAPI ExpDeleteTimer(IN PVOID ObjectBody) { KIRQL OldIrql; PETIMER Timer = ObjectBody; /* Check if it has a Wait List */ if (Timer->WakeTimerListEntry.Flink) { /* Lock the Wake List */ KeAcquireSpinLock(&ExpWakeListLock, &OldIrql); /* Check again, since it might've changed before we locked */ if (Timer->WakeTimerListEntry.Flink) { /* Remove it from the Wait List */ RemoveEntryList(&Timer->WakeTimerListEntry); Timer->WakeTimerListEntry.Flink = NULL; } /* Release the Wake List */ KeReleaseSpinLock(&ExpWakeListLock, OldIrql); } /* Tell the Kernel to cancel the Timer and flush all queued DPCs */ KeCancelTimer(&Timer->KeTimer); KeFlushQueuedDpcs(); }
// // Called by the system work item to finish the rundown // VOID FxDpc::FlushAndRundown() { FxObject* pObject; // // If we have the KeFlushQueuedDpcs function call it // to ensure the DPC routine is no longer running before // we release the final reference and memory to the framework objects // KeFlushQueuedDpcs(); // // Release our reference count to the associated parent object if present // if (m_Object != NULL) { pObject = m_Object; m_Object = NULL; pObject->RELEASE(this); } // // Perform our final release to ourselves, destroying the FxDpc // RELEASE(this); }
BOOLEAN FxDpc::Cancel( __in BOOLEAN Wait ) { BOOLEAN result; result = KeRemoveQueueDpc(GetDpcPtr()); // // If result == FALSE, then the DPC could already be running. // // If the caller supplies Wait == TRUE, they want to wait and // ensure on return the DPC has finished running. // // The trick here is to implement this without adding execessive // overhead to the "normal" path, such as tracking reference counts, // locking, signaling events to waiting threads, etc. // // So we take the expensive approach for the Cancel call in the // case the caller wants to wait, and misses the DPC window. In // this case we will just do the system wide FlushQueuedDpc's to // ensure the DPC has finished running before return. // if( Wait && !result ) { ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); KeFlushQueuedDpcs(); } return result; }
VOID XenPci_HighSync(PXENPCI_HIGHSYNC_FUNCTION function0, PXENPCI_HIGHSYNC_FUNCTION functionN, PVOID context) { ULONG ActiveProcessorCount; ULONG i; highsync_info_t *highsync_info; KIRQL old_irql; UNREFERENCED_PARAMETER(context); FUNCTION_ENTER(); highsync_info = ExAllocatePoolWithTag(NonPagedPool, sizeof(highsync_info_t), XENPCI_POOL_TAG); RtlZeroMemory(highsync_info, sizeof(highsync_info_t)); KeInitializeEvent(&highsync_info->highsync_complete_event, SynchronizationEvent, FALSE); highsync_info->function0 = function0; highsync_info->functionN = functionN; highsync_info->context = context; highsync_info->sync_level = HIGH_LEVEL; #if (NTDDI_VERSION >= NTDDI_WINXP) ActiveProcessorCount = (ULONG)KeNumberProcessors; #else ActiveProcessorCount = (ULONG)*KeNumberProcessors; #endif /* Go to HIGH_LEVEL to prevent any races with Dpc's on the current processor */ KeRaiseIrql(highsync_info->sync_level, &old_irql); highsync_info->do_spin = TRUE; for (i = 0; i < ActiveProcessorCount; i++) { if (i == 0) KeInitializeDpc(&highsync_info->dpcs[i], XenPci_HighSyncCallFunction0, highsync_info); else KeInitializeDpc(&highsync_info->dpcs[i], XenPci_HighSyncCallFunctionN, highsync_info); KeSetTargetProcessorDpc(&highsync_info->dpcs[i], (CCHAR)i); KeSetImportanceDpc(&highsync_info->dpcs[i], HighImportance); KdPrint((__DRIVER_NAME " queuing Dpc for CPU %d\n", i)); KeInsertQueueDpc(&highsync_info->dpcs[i], NULL, NULL); } KdPrint((__DRIVER_NAME " All Dpc's queued\n")); KeMemoryBarrier(); KeLowerIrql(old_irql); KdPrint((__DRIVER_NAME " Waiting for highsync_complete_event\n")); KeWaitForSingleObject(&highsync_info->highsync_complete_event, Executive, KernelMode, FALSE, NULL); #if (NTDDI_VERSION >= NTDDI_WINXP) KeFlushQueuedDpcs(); #else { /* just wait 1 second until all DPC's finish - not ideal but it's only for W2K */ LARGE_INTEGER interval; interval.QuadPart = -1 * 1000 * 1000 * 10; /* 1 second */ KeDelayExecutionThread(KernelMode, FALSE, &interval); } #endif ExFreePoolWithTag(highsync_info, XENPCI_POOL_TAG); FUNCTION_EXIT(); }
void BackupRegistersDeInit(HANDLE_DEV dev) { WriteBackupRegistersToRegistry(dev); #ifdef ENABLE_TIMER_DPC KeCancelTimer(timer); KeFlushQueuedDpcs(); //wait for dpc complete SAFE_FREE_POOL(dpc, IVH_BACKUP_POOL_TAG); SAFE_FREE_POOL(timer, IVH_BACKUP_POOL_TAG); #endif }
VOID EventLogStop(PEVENT_LOG EventLog) { PSYS_WRK_ITEM WrkItem = NULL; EventLog->Stopping = 1; KeCancelTimer(&EventLog->Timer); KeFlushQueuedDpcs(); SysWorkerStop(&EventLog->Worker); EventLogFlush(EventLog); }
VOID NotifierTeardown( IN PXENVIF_NOTIFIER Notifier ) { KeFlushQueuedDpcs(); Notifier->Dpcs = 0; Notifier->Frontend = NULL; RtlZeroMemory(&Notifier->Dpc, sizeof (KDPC)); RtlZeroMemory(&Notifier->Lock, sizeof (KSPIN_LOCK)); ASSERT(IsZeroMemory(Notifier, sizeof (XENVIF_NOTIFIER))); __NotifierFree(Notifier); }
NTSTATUS XenUsb_Disconnect(PVOID context, BOOLEAN suspend) { PXENUSB_DEVICE_DATA xudd = (PXENUSB_DEVICE_DATA)context; //PFN_NUMBER pfn; NTSTATUS status; if (xudd->device_state != DEVICE_STATE_ACTIVE && xudd->device_state != DEVICE_STATE_INACTIVE) { FUNCTION_MSG("state not DEVICE_STATE_(IN)ACTIVE, is %d instead\n", xudd->device_state); FUNCTION_EXIT(); return STATUS_SUCCESS; } if (xudd->device_state != DEVICE_STATE_INACTIVE) { xudd->device_state = DEVICE_STATE_DISCONNECTING; status = XnWriteInt32(xudd->handle, XN_BASE_FRONTEND, "state", XenbusStateClosing); while (xudd->backend_state != XenbusStateClosing && xudd->backend_state != XenbusStateClosed) { FUNCTION_MSG("Waiting for XenbusStateClosing/Closed\n"); KeWaitForSingleObject(&xudd->backend_event, Executive, KernelMode, FALSE, NULL); } status = XnWriteInt32(xudd->handle, XN_BASE_FRONTEND, "state", XenbusStateClosed); while (xudd->backend_state != XenbusStateClosed) { FUNCTION_MSG("Waiting for XenbusStateClosed\n"); KeWaitForSingleObject(&xudd->backend_event, Executive, KernelMode, FALSE, NULL); } XnUnbindEvent(xudd->handle, xudd->event_channel); #if NTDDI_VERSION < WINXP KeFlushQueuedDpcs(); #endif XnEndAccess(xudd->handle, xudd->conn_sring_gref, FALSE, XENUSB_POOL_TAG); ExFreePoolWithTag(xudd->conn_sring, XENUSB_POOL_TAG); XnEndAccess(xudd->handle, xudd->urb_sring_gref, FALSE, XENUSB_POOL_TAG); ExFreePoolWithTag(xudd->urb_sring, XENUSB_POOL_TAG); } if (!suspend) { XnCloseDevice(xudd->handle); } xudd->device_state = DEVICE_STATE_DISCONNECTED; return STATUS_SUCCESS; }
VOID EvtchnFree( __in PXENIFACE_FDO Fdo, __inout PXENIFACE_EVTCHN_CONTEXT Context ) { ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); XenIfaceDebugPrint(TRACE, "Context %p, LocalPort %d, FO %p\n", Context, Context->LocalPort, Context->FileObject); XENBUS_EVTCHN(Close, &Fdo->EvtchnInterface, Context->Channel); // There may still be a pending event at this time. // Wait for our DPCs to complete. KeFlushQueuedDpcs(); ObDereferenceObject(Context->Event); RtlZeroMemory(Context, sizeof(XENIFACE_EVTCHN_CONTEXT)); ExFreePoolWithTag(Context, XENIFACE_POOL_TAG); }
static void set_timer(unsigned long delta) { if (delta == LKL_TIMER_INIT) return; if (delta == LKL_TIMER_SHUTDOWN) { /* should not deliver timer shutdown twice */ if(timer_done) { DbgPrint("*** LKL_TIMER_SHUTDOWN called when timer_done ***"); while(1) ; } /* deque the timer so it won't be put in signaled state */ KeCancelTimer(&timer); /* timers run on DPCs. This returns after all active * DPCs have executed, which means the timer is * certainly not running nor being schduled after this * point. */ KeFlushQueuedDpcs(); /* signal the timer interrupt we're done */ timer_done = 1; /* the memory barrier is needed because it may be * possible for the compiler/cpu to call * KeReleaseSemaphore before assigning * timer_done. That would make the timer_thread wake * from the wait-for-multiple-objs without noticing * out signalling */ KeMemoryBarrier(); KeReleaseSemaphore(&timer_killer_sem, 0, 1, 0); return; } KeSetTimer(&timer, RtlConvertLongToLargeInteger((unsigned long)(-(delta/100))), NULL); }
NTSTATUS CMiniportWaveRTStream::SetState ( _In_ KSSTATE State_ ) { PAGED_CODE(); NTSTATUS ntStatus = STATUS_SUCCESS; PADAPTERCOMMON pAdapterComm = m_pMiniport->GetAdapterCommObj(); // Spew an event for a pin state change request from portcls //Event type: eMINIPORT_PIN_STATE //Parameter 1: Current linear buffer position //Parameter 2: Current WaveRtBufferWritePosition //Parameter 3: Pin State 0->KS_STOP, 1->KS_ACQUIRE, 2->KS_PAUSE, 3->KS_RUN //Parameter 4:0 pAdapterComm->WriteEtwEvent(eMINIPORT_PIN_STATE, 100, // replace with the correct "Current linear buffer position" m_ulCurrentWritePosition, // replace with the previous WaveRtBufferWritePosition that the drive received State_, // repalce with the correct "Data length completed" 0); // always zero switch (State_) { case KSSTATE_STOP: // Reset DMA m_ullPlayPosition = 0; m_ullWritePosition = 0; m_ullLinearPosition = 0; // Wait until all work items are completed. if (!m_bCapture && !g_DoNotCreateDataFiles) { m_SaveData.WaitAllWorkItems(); } #ifdef SYSVAD_BTH_BYPASS if (m_ScoOpen) { PBTHHFPDEVICECOMMON bthHfpDevice; ASSERT(m_pMiniport->IsBthHfpDevice()); bthHfpDevice = m_pMiniport->GetBthHfpDevice(); // weak ref. ASSERT(bthHfpDevice != NULL); // // Close the SCO connection. // ntStatus = bthHfpDevice->StreamClose(); if (!NT_SUCCESS(ntStatus)) { DPF(D_ERROR, ("SetState: KSSTATE_STOP, StreamClose failed, 0x%x", ntStatus)); } m_ScoOpen = FALSE; } #endif // SYSVAD_BTH_BYPASS break; case KSSTATE_ACQUIRE: #ifdef SYSVAD_BTH_BYPASS if (m_pMiniport->IsBthHfpDevice()) { if(m_ScoOpen == FALSE) { PBTHHFPDEVICECOMMON bthHfpDevice; bthHfpDevice = m_pMiniport->GetBthHfpDevice(); // weak ref. ASSERT(bthHfpDevice != NULL); // // Open the SCO connection. // ntStatus = bthHfpDevice->StreamOpen(); IF_FAILED_ACTION_JUMP( ntStatus, DPF(D_ERROR, ("SetState: KSSTATE_ACQUIRE, StreamOpen failed, 0x%x", ntStatus)), Done); m_ScoOpen = TRUE; } } #endif // SYSVAD_BTH_BYPASS break; case KSSTATE_PAUSE: ULONGLONG ullPositionTemp; // Pause DMA if (m_ulNotificationIntervalMs > 0) { KeCancelTimer(m_pNotificationTimer); KeFlushQueuedDpcs(); } // This call updates the linear buffer position. GetLinearBufferPosition(&ullPositionTemp, NULL); break; case KSSTATE_RUN: // Start DMA LARGE_INTEGER ullPerfCounterTemp; ullPerfCounterTemp = KeQueryPerformanceCounter(&m_ullPerformanceCounterFrequency); m_ullDmaTimeStamp = KSCONVERT_PERFORMANCE_TIME(m_ullPerformanceCounterFrequency.QuadPart, ullPerfCounterTemp); m_hnsElapsedTimeCarryForward = 0; if (m_ulNotificationIntervalMs > 0) { LARGE_INTEGER delay; delay.HighPart = 0; delay.LowPart = m_ulNotificationIntervalMs * HNSTIME_PER_MILLISECOND * -1; KeSetTimerEx ( m_pNotificationTimer, delay, m_ulNotificationIntervalMs, m_pNotificationDpc ); } break; } m_KsState = State_; #ifdef SYSVAD_BTH_BYPASS Done: #endif // SYSVAD_BTH_BYPASS return ntStatus; }
CMiniportWaveRTStream::~CMiniportWaveRTStream ( void ) /*++ Routine Description: Destructor for wavertstream Arguments: Return Value: NT status code. --*/ { PAGED_CODE(); if (NULL != m_pMiniport) { if (m_bUnregisterStream) { m_pMiniport->StreamClosed(m_ulPin, this); m_bUnregisterStream = FALSE; } m_pMiniport->Release(); m_pMiniport = NULL; } if (m_pDpc) { ExFreePoolWithTag( m_pDpc, MINWAVERTSTREAM_POOLTAG ); m_pDpc = NULL; } if (m_pTimer) { ExFreePoolWithTag( m_pTimer, MINWAVERTSTREAM_POOLTAG ); m_pTimer = NULL; } if (m_pbMuted) { ExFreePoolWithTag( m_pbMuted, MINWAVERTSTREAM_POOLTAG ); m_pbMuted = NULL; } if (m_plVolumeLevel) { ExFreePoolWithTag( m_plVolumeLevel, MINWAVERTSTREAM_POOLTAG ); m_plVolumeLevel = NULL; } if (m_plPeakMeter) { ExFreePoolWithTag( m_plPeakMeter, MINWAVERTSTREAM_POOLTAG ); m_plPeakMeter = NULL; } if (m_pWfExt) { ExFreePoolWithTag( m_pWfExt, MINWAVERTSTREAM_POOLTAG ); m_pWfExt = NULL; } if (m_pNotificationTimer) { KeCancelTimer(m_pNotificationTimer); ExFreePoolWithTag(m_pNotificationTimer, MINWAVERTSTREAM_POOLTAG); } // Since we just cancelled the notification timer, wait for all queued // DPCs to complete before we free the notification DPC. // KeFlushQueuedDpcs(); if (m_pNotificationDpc) { ExFreePoolWithTag( m_pNotificationDpc, MINWAVERTSTREAM_POOLTAG ); } #ifdef SYSVAD_BTH_BYPASS ASSERT(m_ScoOpen == FALSE); #endif // SYSVAD_BTH_BYPASS DPF_ENTER(("[CMiniportWaveRTStream::~CMiniportWaveRTStream]")); } // ~CMiniportWaveRTStream
VOID natDeinitFwSession() { KeCancelTimer(&g_FwSessionTimer); KeFlushQueuedDpcs(); }
VOID NICStopTheDatapath( _In_ PMP_ADAPTER Adapter) /*++ Routine Description: This function prevents future sends and receives on the data path, then prepares the adapter to reach an idle state. Although the adapter is entering an idle state, there may still be outstanding NBLs that haven't been returned by a protocol. Call NICIsBusy to check if NBLs are still outstanding. Runs at IRQL == PASSIVE_LEVEL. Arguments: Adapter Pointer to our adapter Return Value: None. --*/ { BOOLEAN fResetCancelled, fSendCancelled; PLIST_ENTRY ReceiveListEntry; DEBUGP(MP_TRACE, "[%p] ---> NICStopTheDatapath.\n", Adapter); PAGED_CODE(); // // Remove this adapter from consideration for future receives. // MPDetachAdapter(Adapter); // // Free any queued send operations // TXFlushSendQueue(Adapter, NDIS_STATUS_FAILURE); // // Prevent new calls to NICAsyncResetOrPauseDpc // fResetCancelled = NdisCancelTimerObject(Adapter->AsyncBusyCheckTimer); // // Prevent new calls to RXReceiveIndicateDpc. // for(ReceiveListEntry = Adapter->RecvDpcList.Flink; ReceiveListEntry != &Adapter->RecvDpcList; ReceiveListEntry = ReceiveListEntry->Flink) { PMP_ADAPTER_RECEIVE_DPC ReceiveDpc = CONTAINING_RECORD(ReceiveListEntry, MP_ADAPTER_RECEIVE_DPC, Entry); KeRemoveQueueDpc(&ReceiveDpc->Dpc); } // // Prevent new calls to TXSendCompleteDpc. // fSendCancelled = NdisCancelTimerObject(Adapter->SendCompleteTimer); // // Wait for any DPCs (like our reset and recv timers) that were in-progress // to run to completion. This is slightly expensive to call, but we don't // mind calling it during MiniportHaltEx, since it's not a performance- // sensitive path. // KeFlushQueuedDpcs(); if (fSendCancelled) { // Free resources associated with a pending (but cancelled) send } if (fResetCancelled) { // Free resources associated with a pending (but cancelled) reset } // // Double-check that there are still no queued receive operations // for(ReceiveListEntry = Adapter->RecvDpcList.Flink; ReceiveListEntry != &Adapter->RecvDpcList; ReceiveListEntry = ReceiveListEntry->Flink) { RXFlushReceiveQueue(Adapter, CONTAINING_RECORD(ReceiveListEntry, MP_ADAPTER_RECEIVE_DPC, Entry)); } // // Double-check that there are still no queued send operations // TXFlushSendQueue(Adapter, NDIS_STATUS_FAILURE); DEBUGP(MP_TRACE, "[%p] <--- NICStopTheDatapath.\n", Adapter); }