Uso de la inicialización de One-Time
En los ejemplos siguientes se muestra el uso de las funciones de inicialización única.
Ejemplo sincrónico
En este ejemplo, la g_InitOnce
variable global es la estructura de inicialización única. Se inicializa estáticamente mediante INIT_ONCE_STATIC_INIT.
La OpenEventHandleSync
función devuelve un identificador a un evento que se crea una sola vez. Llama a la función InitOnceExecuteOnce Para ejecutar el código de inicialización contenido en la InitHandleFunction
función de devolución de llamada. Si la función de devolución de llamada se realiza correctamente, OpenEventHandleSync
devuelve el identificador de eventos devuelto en lpContext; de lo contrario, devuelve INVALID_HANDLE_VALUE.
La InitHandleFunction
función es la función de devolución de llamada de inicialización única.
InitHandleFunction
llama a la función CreateEvent para crear el evento y devuelve el identificador de eventos en el parámetro lpContext .
#define _WIN32_WINNT 0x0600
#include <windows.h>
// Global variable for one-time initialization structure
INIT_ONCE g_InitOnce = INIT_ONCE_STATIC_INIT; // Static initialization
// Initialization callback function
BOOL CALLBACK InitHandleFunction (
PINIT_ONCE InitOnce,
PVOID Parameter,
PVOID *lpContext);
// Returns a handle to an event object that is created only once
HANDLE OpenEventHandleSync()
{
PVOID lpContext;
BOOL bStatus;
// Execute the initialization callback function
bStatus = InitOnceExecuteOnce(&g_InitOnce, // One-time initialization structure
InitHandleFunction, // Pointer to initialization callback function
NULL, // Optional parameter to callback function (not used)
&lpContext); // Receives pointer to event object stored in g_InitOnce
// InitOnceExecuteOnce function succeeded. Return event object.
if (bStatus)
{
return (HANDLE)lpContext;
}
else
{
return (INVALID_HANDLE_VALUE);
}
}
// Initialization callback function that creates the event object
BOOL CALLBACK InitHandleFunction (
PINIT_ONCE InitOnce, // Pointer to one-time initialization structure
PVOID Parameter, // Optional parameter passed by InitOnceExecuteOnce
PVOID *lpContext) // Receives pointer to event object
{
HANDLE hEvent;
// Create event object
hEvent = CreateEvent(NULL, // Default security descriptor
TRUE, // Manual-reset event object
TRUE, // Initial state of object is signaled
NULL); // Object is unnamed
// Event object creation failed.
if (NULL == hEvent)
{
return FALSE;
}
// Event object creation succeeded.
else
{
*lpContext = hEvent;
return TRUE;
}
}
Ejemplo asincrónico
En este ejemplo, la g_InitOnce
variable global es la estructura de inicialización única. Se inicializa estáticamente mediante INIT_ONCE_STATIC_INIT.
La OpenEventHandleAsync
función devuelve un identificador a un evento que se crea una sola vez.
OpenEventHandleAsync
llama a la función InitOnceBeginInitialize para especificar el estado de inicialización.
Si la llamada se realiza correctamente, el código comprueba el valor del parámetro fPending para determinar si se debe crear el evento o simplemente devolver un identificador al evento creado por otro subproceso. Si fPending es FALSE, la inicialización ya se ha completado, por lo que OpenEventHandleAsync
devuelve el identificador de eventos devuelto en el parámetro lpContext . De lo contrario, llama a la función CreateEvent para crear el evento y la función InitOnceComplete para completar la inicialización.
Si la llamada a InitOnceComplete se realiza correctamente, OpenEventHandleAsync
devuelve el nuevo identificador de eventos. De lo contrario, cierra el identificador de eventos y llama a InitOnceBeginInitialize con INIT_ONCE_CHECK_ONLY para determinar si se produjo un error de inicialización o si otro subproceso completó la inicialización.
Si otro subproceso completó la inicialización, OpenEventHandleAsync
devuelve el identificador de eventos devuelto en lpContext. De lo contrario, devuelve INVALID_HANDLE_VALUE.
#define _WIN32_WINNT 0x0600
#include <windows.h>
// Global variable for one-time initialization structure
INIT_ONCE g_InitOnce = INIT_ONCE_STATIC_INIT; // Static initialization
// Returns a handle to an event object that is created only once
HANDLE OpenEventHandleAsync()
{
PVOID lpContext;
BOOL fStatus;
BOOL fPending;
HANDLE hEvent;
// Begin one-time initialization
fStatus = InitOnceBeginInitialize(&g_InitOnce, // Pointer to one-time initialization structure
INIT_ONCE_ASYNC, // Asynchronous one-time initialization
&fPending, // Receives initialization status
&lpContext); // Receives pointer to data in g_InitOnce
// InitOnceBeginInitialize function failed.
if (!fStatus)
{
return (INVALID_HANDLE_VALUE);
}
// Initialization has already completed and lpContext contains event object.
if (!fPending)
{
return (HANDLE)lpContext;
}
// Create event object for one-time initialization.
hEvent = CreateEvent(NULL, // Default security descriptor
TRUE, // Manual-reset event object
TRUE, // Initial state of object is signaled
NULL); // Object is unnamed
// Event object creation failed.
if (NULL == hEvent)
{
return (INVALID_HANDLE_VALUE);
}
// Complete one-time initialization.
fStatus = InitOnceComplete(&g_InitOnce, // Pointer to one-time initialization structure
INIT_ONCE_ASYNC, // Asynchronous initialization
(PVOID)hEvent); // Pointer to event object to be stored in g_InitOnce
// InitOnceComplete function succeeded. Return event object.
if (fStatus)
{
return hEvent;
}
// Initialization has already completed. Free the local event.
CloseHandle(hEvent);
// Retrieve the final context data.
fStatus = InitOnceBeginInitialize(&g_InitOnce, // Pointer to one-time initialization structure
INIT_ONCE_CHECK_ONLY, // Check whether initialization is complete
&fPending, // Receives initialization status
&lpContext); // Receives pointer to event object in g_InitOnce
// Initialization is complete. Return handle.
if (fStatus && !fPending)
{
return (HANDLE)lpContext;
}
else
{
return INVALID_HANDLE_VALUE;
}
}
Temas relacionados