InitializeDateLogHandle

Allocate and initialize a new date log, range, or holidays handle

Overview

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.

Purpose

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).

Handle Types

DateHandleTypeDescription
HandleIsForDatelogA complete date log collection. Requires a holidays handle.
HandleIsForRangeA date range subset, typically temporary or used for merge operations (see MergeDateLogHandle and ConvertDateLogHandle). Requires a holidays handle.
HandleIsForHolidaysA market holidays collection used for market-day validation. hHolidays must be NULL.

Key Features

Function Signature


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
);
This signature matches datelog.h. An earlier revision of this page listed a trailing dwFlags parameter instead of dwMaximumLength; that parameter does not exist in the header.

Parameters

pSecAttr

[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.

dwMaximumLength

[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.

hHolidays

[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.

hDateLogHandle

[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.

HandleType

[In] DateHandleType

One of HandleIsForDatelog (1), HandleIsForRange (2) or HandleIsForHolidays (3).

Return Values

ValueMeaning
S_OKHandle created and returned via hDateLogHandle.
HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER)hHolidays is NULL when required for the handle type.
ERR_BAD_HANDLE_TYPEHandleType 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.
An earlier revision of this page documented ERROR_INVALID_PARAMETER for an invalid HandleType; date_error_h defines ERR_BAD_HANDLE_TYPE for that condition. Treat any failing HRESULT as failure.

Behavior and Operations

Alloc Context
→
Create Mutex/CritSec
→
Duplicate Holidays
→
Alloc PDATE_LOG
On any failure, all partially-constructed resources are torn down via CloseDateLogHandle()/FreeDateLogHandleContext() so no leak occurs.

Remarks

Thread Safety

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.

Handle Lifetime and Reference Counting

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.

Ownership

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.

Ordering

See Also

Sample Code


#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;
}