Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Životní cyklus vyrovnávací paměti zahrnuje čas od okamžiku vytvoření vyrovnávací paměti do okamžiku odstranění. Toto téma popisuje scénáře použití vyrovnávací paměti a jejich vliv na odstranění vyrovnávací paměti.
V rozhraní ovladače režimu jádra (KMDF) objekt požadavku představuje vstupně-výstupní požadavek. Každý objekt požadavku je přidružený k jednomu nebo více paměťovým objektům a každý objekt paměti představuje vyrovnávací paměť, která se používá pro vstup nebo výstup v požadavku.
Když architektura vytvoří objekty požadavku a paměti, které představují příchozí vstupně-výstupní požadavek, nastaví objekt požadavku jako nadřazený objekt přidružené paměti. Objekt paměti proto nemůže trvat déle, než je doba života objektu požadavku. Když ovladač založený na frameworku dokončí vstupně-výstupní požadavek, framework odstraní objekt požadavku a objekt paměti, takže popisovače těchto dvou objektů se stanou neplatnými.
Základní vyrovnávací paměť se ale liší. V závislosti na tom, která komponenta vytvořila vyrovnávací paměť a způsob vytvoření vyrovnávací paměti, může mít vyrovnávací paměť počet odkazů a může být vlastněna objektem paměti, nebo ne. Pokud objekt paměti vlastní vyrovnávací paměť, pak vyrovnávací paměť má referenční počet a její životnost je omezena na životnost paměťového objektu. Pokud některá jiná komponenta vytvořila vyrovnávací paměť, životnost vyrovnávací paměti a objekt paměti nesouvisí.
Ovladač založený na rozhraní může také vytvořit vlastní objekty požadavků pro odesílání do vstupně-výstupních cílů. Žádost vytvořená ovladačem může znovu použít existující objekt paměti, který ovladač přijal v žádosti o vstupně-výstupní operace. Ovladač, který často odesílá požadavky na vstupně-výstupní cíle, může znovu použít objekty požadavku , které vytvoří.
Pochopení životnosti objektu požadavku, objektu paměti a základní vyrovnávací paměti je důležité, aby se ovladač nepokusil odkazovat na neplatný popisovač nebo ukazatel vyrovnávací paměti.
Zvažte následující scénáře použití:
- Scénář 1: Ovladač obdrží vstupně-výstupní požadavek z KMDF, zpracuje ho a dokončí ho.
- Scénář 2: Ovladač obdrží vstupně-výstupní požadavek z KMDF a předá ho do cíle vstupně-výstupních operací.
- Scénář 3: Ovladač vydává V/V požadavek, který používá existující objekt paměti.
- Scénář 4: Ovladač vydává vstupně-výstupní požadavek, který používá nový objekt paměti.
- Scénář 5: Ovladač znovu použije objekt požadavku, který vytvořil.
Scénář 1: Ovladač obdrží vstupně-výstupní požadavek z KMDF, zpracuje ho a dokončí ho.
V nejjednodušším scénáři služba KMDF odešle požadavek na ovladač, který provede vstupně-výstupní operace a dokončí požadavek. V tomto případě může být základní vyrovnávací paměť vytvořena aplikací v uživatelském režimu, jiným ovladačem, nebo samotným operačním systémem. Informace o přístupu k vyrovnávacím pamětím naleznete v tématu Přístup k vyrovnávacím pamětím dat v ovladačích Framework-Based.
Po dokončení požadavku ovladač rozhraní odstraní objekt paměti. Ukazatel bufferu je následně neplatný.
Scénář 2: Ovladač obdrží vstupně-výstupní požadavek z KMDF a předá ho do cíle vstupně-výstupních operací.
V tomto scénáři ovladač předá požadavek cíli vstupně-výstupních operací. Následující ukázkový kód ukazuje, jak ovladač načte popisovač objektu paměti z příchozího objektu požadavku, naformátuje požadavek tak, aby se odeslal do cíle vstupně-výstupních operací, a odešle požadavek:
VOID
EvtIoRead(
IN WDFQUEUE Queue,
IN WDFREQUEST Request,
IN size_t Length
)
{
NTSTATUS status;
WDFMEMORY memory;
WDFIOTARGET ioTarget;
BOOLEAN ret;
ioTarget = WdfDeviceGetIoTarget(WdfIoQueueGetDevice(Queue));
status = WdfRequestRetrieveOutputMemory(Request, &memory);
if (!NT_SUCCESS(status)) {
goto End;
}
status = WdfIoTargetFormatRequestForRead(ioTarget,
Request,
memory,
NULL,
NULL);
if (!NT_SUCCESS(status)) {
goto End;
}
WdfRequestSetCompletionRoutine(Request,
RequestCompletionRoutine,
WDF_NO_CONTEXT);
ret = WdfRequestSend (Request, ioTarget, WDF_NO_SEND_OPTIONS);
if (!ret) {
status = WdfRequestGetStatus (Request);
goto End;
}
return;
End:
WdfRequestComplete(Request, status);
return;
}
Jakmile cíl vstupně-výstupních operací dokončí požadavek, rámec zavolá funkci dokončení, kterou ovladač pro požadavek nastavil. Následující kód ukazuje jednoduché zpětné volání dokončení:
VOID
RequestCompletionRoutine(
IN WDFREQUEST Request,
IN WDFIOTARGET Target,
PWDF_REQUEST_COMPLETION_PARAMS CompletionParams,
IN WDFCONTEXT Context
)
{
UNREFERENCED_PARAMETER(Target);
UNREFERENCED_PARAMETER(Context);
WdfRequestComplete(Request, CompletionParams->IoStatus.Status);
return;
}
Když ovladač volá WdfRequestComplete ze zpětného volání dokončení, framework odstraní objekt paměti. Popisovač paměťového objektu, který ovladač načetl, je nyní neplatný.
Scénář 3: Ovladač vydává V/V požadavek, který používá existující objekt paměti.
Některé ovladače vydávají vlastní vstupně-výstupní požadavky a odesílají je do cílů vstupně-výstupních operací, které jsou reprezentovány cílovými objekty vstupně-výstupních operací. Ovladač může buď vytvořit vlastní objekt požadavku, nebo znovu použít objekt požadavku vytvořený architekturou. Pomocí některé z technik může ovladač znovu použít objekt paměti z předchozího požadavku. Ovladač nesmí změnit podkladovou vyrovnávací paměť, ale při formátování nového V/V požadavku může předat posun vyrovnávací paměti.
Informace o formátování nového V/V požadavku, který používá existující objekt paměti, naleznete v tématu Odesílání vstupně-výstupních požadavků na obecné vstupně-výstupní cíle.
Když framework naformátuje požadavek na odeslání do cíle V/V, bere referenci na recyklovaný objekt paměti jménem objektu cíle V/V. Cílový vstupně-výstupní objekt zachová tento odkaz, dokud nedojde k některé z následujících akcí:
- Žádost byla dokončena.
- Ovladač znovu přeformátuje objekt požadavku voláním jedné z WdfIoTargetFormatRequestXxx nebo WdfIoTargetSendXxxSynchronously metody. Další informace o těchto metodách naleznete v tématu Metody objektu cíle I/O frameworku.
- Ovladač volá WdfRequestReuse.
Když je nový V/V požadavek dokončen, rámec zavolá zpětné volání dokončení V/V, které pro tento požadavek nastavil ovladač. V tomto okamžiku objekt cíl vstupně-výstupní operace stále obsahuje odkaz na objekt paměti. Proto v zpětném volání při dokončení vstupně-výstupních operací musí ovladač volat WdfRequestReuse na objekt požadavku vytvořeného ovladačem před dokončením původního požadavku, při kterém byl objekt paměti načten. Pokud ovladač nevolá WdfRequestReuse, dojde ke kontrole chyb kvůli dodatečnému odkazu.
Scénář 4: Ovladač vydává vstupně-výstupní požadavek, který používá nový objekt paměti.
Architektura poskytuje tři způsoby, jak ovladače vytvářet nové paměťové objekty v závislosti na zdroji podkladové vyrovnávací paměti. Další informace naleznete v tématu Použití vyrovnávací paměti.
Pokud je vyrovnávací paměť přidělena architekturou nebo ze seznamu vyhledávání vytvořeného ovladačem, objekt paměti vlastní vyrovnávací paměť, takže ukazatel vyrovnávací paměti zůstane platný, pokud existuje objekt paměti. Ovladače, které vydávají asynchronní vstupně-výstupní požadavky, by měly vždy používat vyrovnávací paměti vlastněné objekty paměti, aby architektura zajistila zachování vyrovnávacích pamětí, dokud se požadavek na vstupně-výstupní operace nedokončil zpět k vydávajícímu ovladači.
Pokud ovladač přiřadí dříve přidělenou vyrovnávací paměť novému objektu paměti voláním WdfMemoryCreatePreallocated, objekt paměti nevlastní vyrovnávací paměť. V tomto případě nesouvisí životnost objektu paměti a životnost podkladové vyrovnávací paměti. Ovladač musí spravovat životnost vyrovnávací paměti a nesmí se pokoušet použít neplatný ukazatel vyrovnávací paměti.
Scénář 5: Ovladač znovu použije objekt požadavku, který vytvořil.
Ovladač může znovu použít objekty požadavku, které vytvoří, ale musí znovu inicializovat každý takový objekt voláním WdfRequestReuse před každým opětovným použitím. Další informace naleznete v tématu Opětovné použití objektů žádosti rámce.
Vzorový kód, který znovu inicializuje objekt požadavku, najdete v ukázkách Toustovač a NdisEdge , které jsou k dispozici s verzí KMDF.