Allocate and initialize a new date log, range, or holidays handle
InitializeDateLogHandle allocates a new shared DATE_CONTEXT (mutex, critical section, and a magic number selected by HandleType) and a new date log wrapper around it, optionally duplicating a supplied holidays handle for date log and date range handle types. The resulting handle is returned ready for use with LoadDateLogHandle.
This is the entry point of the library. Every other function that takes a DATE_LOG_HANDLE, DATE_RANGE_HANDLE or HOLIDAYS_HANDLE starts from a handle created here (or from a duplicate made with DuplicateDateLogHandle).
| DateHandleType | Description |
|---|---|
HandleIsForDatelog | A complete date log collection. Requires a holidays handle. |
HandleIsForRange | A date range subset, typically temporary or used for merge operations (see MergeDateLogHandle and ConvertDateLogHandle). Requires a holidays handle. |
HandleIsForHolidays | A market holidays collection used for market-day validation. hHolidays must be NULL. |
HRESULT _Must_inspect_result_ _Success_(SUCCEEDED(return)) InitializeDateLogHandle(
_In_opt_ PSECURITY_ATTRIBUTES pSecAttr,
_In_opt_ const DWORD dwMaximumLength,
_In_opt_ HOLIDAYS_HANDLE hHolidays,
_Out_ DATE_LOG_HANDLE * hDateLogHandle,
_In_ DateHandleType HandleType
);
dwFlags parameter instead of dwMaximumLength; that parameter does not exist in the header.[In, Optional] PSECURITY_ATTRIBUTES
Security attributes passed to CreateMutex() for both the context mutex and the handle's own mutex. Pass NULL for default security. The structure is only read during the call.
[In, Optional] const DWORD
Maximum number of date items the collection can hold. The library-wide upper bound is DATE_LOG_MAX (0x591C8, 370,120 items); the current value can be read later with GetDateCollectionMaximumLength. See date_error_h for ERR_MAX_DATELOG_REACHED and ERR_DATELOG_LENGTH_MAX.
[In, Optional] HOLIDAYS_HANDLE
Required (non-NULL) when HandleType is HandleIsForDatelog or HandleIsForRange; it is duplicated internally via DuplicateDateLogHandle, so the caller keeps ownership of its own handle and must still close it.
Must be NULL when HandleType is HandleIsForHolidays.
[Out] DATE_LOG_HANDLE *
Receives the newly created handle. Must not be NULL. The caller owns the handle and must close it exactly once with CloseDateLogHandle. For HandleIsForHolidays and HandleIsForRange the same pointer type is used.
[In] DateHandleType
One of HandleIsForDatelog (1), HandleIsForRange (2) or HandleIsForHolidays (3).
| Value | Meaning |
|---|---|
S_OK | Handle created and returned via hDateLogHandle. |
HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER) | hHolidays is NULL when required for the handle type. |
ERR_BAD_HANDLE_TYPE | HandleType is not one of HandleIsForDatelog, HandleIsForRange or HandleIsForHolidays (as defined in date_error_h). |
HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY) | Allocation of the context or handle failed. |
ERROR_INVALID_PARAMETER for an invalid HandleType; date_error_h defines ERR_BAD_HANDLE_TYPE for that condition. Treat any failing HRESULT as failure.CloseDateLogHandle()/FreeDateLogHandleContext() so no leak occurs.Each handle has its own mutex and shares a context mutex and critical section with its duplicates. The context is designed for concurrent access; give each thread its own handle with DuplicateDateLogHandle so threads do not contend on one handle's mutex.
A newly created handle starts a context with one reference. DuplicateDateLogHandle increments the count and CloseDateLogHandle decrements it; the shared context (date log core, holidays handle, ODBC connections) is freed when the last handle is closed. Closing the last handle of a date log or range context also closes its internal reference to the holidays handle.
The caller owns every handle returned through hDateLogHandle, including the holidays handle created with HandleIsForHolidays that was passed to a date log. Close the date log and the original holidays handle each exactly once.
HandleIsForHolidays, hHolidays = NULL).
#include <stdio.h>
#include <Windows.h>
#include "datelog.h"
int main(void)
{
HRESULT hr = E_FAIL;
HOLIDAYS_HANDLE hHolidays = NULL;
DATE_LOG_HANDLE hDateLog = NULL;
DATE_LOG_HANDLE hDateLogCopy = NULL;
DATE_RANGE_HANDLE hRange = NULL;
DATE_LOG_HANDLE hBad = NULL;
int exitCode = 1;
/* 1. Holidays collection: hHolidays must be NULL for this handle type. */
hr = InitializeDateLogHandle(NULL, DATE_LOG_MAX, NULL, &hHolidays, HandleIsForHolidays);
if (FAILED(hr)) {
printf("Holidays handle creation failed: 0x%08lX\n", (unsigned long)hr);
goto cleanup;
}
/* 2. Date log that references the holidays collection. */
hr = InitializeDateLogHandle(NULL, DATE_LOG_MAX, hHolidays, &hDateLog, HandleIsForDatelog);
if (FAILED(hr)) {
printf("Date log creation failed: 0x%08lX\n", (unsigned long)hr);
goto cleanup;
}
/* 3. A date range handle, for example as a merge source. */
hr = InitializeDateLogHandle(NULL, DATE_LOG_MAX, hHolidays, &hRange, HandleIsForRange);
if (FAILED(hr)) {
printf("Range creation failed: 0x%08lX\n", (unsigned long)hr);
goto cleanup;
}
/* 4. A second handle on the same shared context for another thread. */
hr = DuplicateDateLogHandle(hDateLog, &hDateLogCopy);
if (FAILED(hr)) {
printf("DuplicateDateLogHandle failed: 0x%08lX\n", (unsigned long)hr);
goto cleanup;
}
printf("Date log valid: %s\n", IsValidDateLogHandle(hDateLog) ? "yes" : "no");
printf("Items: %lu of at most %lu\n",
GetDateCollectionLength(hDateLog), GetDateCollectionMaximumLength(hDateLog));
/* 5. A date log without a holidays handle is rejected; hBad stays NULL. */
hr = InitializeDateLogHandle(NULL, DATE_LOG_MAX, NULL, &hBad, HandleIsForDatelog);
if (FAILED(hr)) {
printf("Creation without holidays rejected: 0x%08lX\n", (unsigned long)hr);
} else {
CloseDateLogHandle(hBad);
hBad = NULL;
}
exitCode = 0;
cleanup:
/* Each handle is closed exactly once; the shared context is freed with its last handle. */
if (hDateLogCopy != NULL) {
CloseDateLogHandle(hDateLogCopy);
}
if (hRange != NULL) {
CloseDateLogHandle(hRange);
}
if (hDateLog != NULL) {
CloseDateLogHandle(hDateLog);
}
if (hHolidays != NULL) {
CloseDateLogHandle(hHolidays);
}
return exitCode;
}