다음을 통해 공유


WdfWorkItemEnqueue 함수(wdfworkitem.h)

[KMDF 및 UMDF에 적용]

WdfWorkItemEnqueue 메서드는 지정된 프레임워크 작업 항목 개체를 시스템의 작업 항목 큐에 추가합니다.

구문

void WdfWorkItemEnqueue(
  [in] WDFWORKITEM WorkItem
);

매개 변수

[in] WorkItem

WdfWorkItemCreate에 대한 이전 호출에서 가져온 프레임워크 작업 항목 개체에 대한 핸들입니다.

반환 값

없음

설명

드라이버가 잘못된 개체 핸들을 제공하는 경우 버그 검사 발생합니다.

드라이버가 WdfWorkItemCreate 를 호출하여 작업 항목을 만든 후 드라이버는 WdfWorkItemEnqueue 를 호출하여 작업 항목을 시스템의 작업 항목 큐에 추가해야 합니다. 시스템 작업자 스레드는 이후에 큐에서 작업 항목을 제거하고 작업 항목의 EvtWorkItem 콜백 함수를 호출합니다. 시스템에서 작업 항목이 큐에 추가된 순서대로 제거됩니다.

드라이버는 WdfWorkItemEnqueue를 호출하기 전에 일반적으로 작업 항목 개체의 컨텍스트 메모리를 사용하여 작업 항목에 대한 정보를 저장합니다. EvtWorkItem 콜백 함수는 이 정보를 사용하여 수행해야 하는 작업을 결정합니다.

KMDF 버전 1.7 이상에서는 드라이버가 작업 항목 개체를 다시 사용하는 경우 시스템 작업자 스레드가 작업 항목을 큐에서 제거한 후 드라이버의 EvtWorkItem 콜백 함수를 호출하기 전에 드라이버가 동일한 작업 항목에 대해 WdfWorkItemEnqueue를 다시 호출할 수 있습니다. 그러나 KMDF는 작업 항목이 이미 있는 경우 큐에 추가하지 않습니다. 따라서 EvtWorkItem 콜백 함수는 호출할 때마다 대기 중인 모든 작업을 처리해야 합니다.

EvtWorkItem 콜백 함수가 실행되는 동안 드라이버가 WdfWorkItemEnqueue를 호출하여 다른 작업 항목을 큐에 추가할 수도 있습니다. 두 번째 작업 항목의 EvtWorkItem 콜백은 첫 번째 작업 항목이 완료되기 전에 실행될 수도 있습니다.

버전 1.7 이전의 KMDF 버전에서 드라이버가 작업 항목 개체를 다시 사용하는 경우 시스템 작업자 스레드가 작업 항목을 큐에서 제거하고 EvtWorkItem 콜백 함수를 호출할 때까지 동일한 작업 항목에 대해 WdfWorkItemEnqueue를 다시 호출해서는 안 됩니다.

작업 항목에 대한 자세한 내용은 프레임워크 작업 항목 사용을 참조하세요.

예제

이 섹션에서는 두 가지 예제를 포함합니다. 첫 번째 예제에서는 KMDF 버전 1.7 이상에 대한 큐에 작업 항목을 추가하는 방법을 보여줍니다. 두 번째 예제에서는 버전 1.7 이전 KMDF 버전의 큐에 작업 항목을 추가하는 방법을 보여줍니다.

예제 1: KMDF 버전 1.7 이상

다음 코드 예제에서는 작업 항목 개체의 컨텍스트 메모리에 대한 포인터를 반환하는 로컬 루틴을 호출합니다. 이 예제에서는 개체의 컨텍스트 메모리에 정보를 설정한 다음 WdfWorkItemEnqueue를 호출합니다. 드라이버의 EvtWorkItem 콜백 함수는 나중에 작업 항목 개체에서 정보를 검색합니다.

PMY_CONTEXT_TYPE context;

context = GetWorkItemContext(hWorkItem);
context->FdoData = FdoData;
context->Argument1 = Context1;
context->Argument2 = Context2;

WdfWorkItemEnqueue(hWorkItem);

드라이버의 EvtWorkItem 콜백 함수에는 다음 코드가 포함되어 있습니다.

MyWorkItemCallback (
    IN WDFWORKITEM hWorkItem
    )
{
    PMY_CONTEXT_TYPE context;

    context = GetWorkItemContext(hWorkItem);

    //
    // Do work here.
    //
    ...
    //
    return;
}

예제 2: 1.7 이전 KMDF 버전

다음 코드 예제에서는 작업 항목 개체의 컨텍스트 메모리에 대한 포인터를 반환하는 로컬 루틴을 호출합니다. 이 예제에서는 개체의 컨텍스트 메모리에 정보를 설정하고 상태 변수를 "사용 중"으로 설정한 다음 WdfWorkItemEnqueue를 호출합니다. 드라이버의 EvtWorkItem 콜백 함수는 나중에 작업 항목 개체에서 정보를 검색합니다.

typedef enum _WORKITEM_STATE {
    WORKITEM_STATE_FREE =0,
    WORKITEM_STATE_BUSY = 1
} WORKITEM_STATE;
...
PMY_CONTEXT_TYPE context;

context = GetWorkItemContext(hWorkItem);
context->FdoData = FdoData;
context->Argument1 = Context1;
context->Argument2 = Context2;

if (InterlockedCompareExchange(
                               (PLONG)&context->WorkItemState,
                               WORKITEM_STATE_BUSY,
                               WORKITEM_STATE_FREE
                               ) == WORKITEM_STATE_FREE) {
 WdfWorkItemEnqueue(hWorkItem);
}

드라이버의 EvtWorkItem 콜백 함수에는 다음 코드가 포함되어 있습니다. return 문 바로 앞에서 코드는 작업 항목 개체의 상태 변수를 "free"로 설정하여 드라이버가 개체를 다시 큐에 대기할 수 있도록 합니다.

MyWorkItemCallback (
    IN WDFWORKITEM hWorkItem
    )
{
    PMY_CONTEXT_TYPE context;
    LONG result;

    context = GetWorkItemContext(hWorkItem);

    //
    // Do work here.
    //
    ...
    //
    // Reset object state.
    //
    result = InterlockedExchange(
                                 (PLONG)&context->WorkItemState,
                                 WORKITEM_STATE_FREE
                                 );
    ASSERT(result == WORKITEM_STATE_BUSY);
    return;
}

요구 사항

요구 사항
대상 플랫폼 유니버설
최소 KMDF 버전 1.0
최소 UMDF 버전 2.0
머리글 wdfworkitem.h(Wdf.h 포함)
라이브러리 Wdf01000.sys(KMDF); WUDFx02000.dll(UMDF)
IRQL <= DISPATCH_LEVEL
DDI 규정 준수 규칙 DeferredRequestCompleted(kmdf), DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), RequestCompleted(kmdf), RequestCompletedLocal(kmdf)

추가 정보

EvtWorkItem

InterlockedCompareExchange

InterlockedExchange

WdfWorkItemCreate