{"id":7813,"date":"2012-04-20T07:00:00","date_gmt":"2012-04-20T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2012\/04\/20\/what-does-init_once_ctx_reserved_bits-mean\/"},"modified":"2012-04-20T07:00:00","modified_gmt":"2012-04-20T07:00:00","slug":"what-does-init_once_ctx_reserved_bits-mean","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20120420-00\/?p=7813","title":{"rendered":"What does INIT_ONCE_CTX_RESERVED_BITS mean?"},"content":{"rendered":"<p>\nWindows Vista adds the\n<a HREF=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa363808(v=VS.85).aspx\">\nOne-Time Initialization<\/a>\nfamily of functions\nwhich address a common coding pattern:\nI want a specific chunk of code to run exactly once,\neven in the face of multiple calls from different threads.\nThere are many implementations of this pattern,\nsuch as the infamous\n<a HREF=\"http:\/\/en.wikipedia.org\/wiki\/Double-checked_locking\">\ndouble-checked lock<\/a>.\nThe double-checked lock is very easy to get wrong,\ndue to memory ordering and race conditions,\nso\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2012\/04\/17\/10294294.aspx\">\nthe kernel folks<\/a>\ndecided to write it for you.\n<\/p>\n<p>\nThe straightforward way of using a one-time-initialization\nobject is to have it protect the initialization of some other\nobject.\nFor example, you might have it protect a static object:\n<\/p>\n<pre>\nINIT_ONCE GizmoInitOnce = INIT_ONCE_STATIC_INIT;\nGizmo ProtectedGizmo;\nBOOL CALLBACK InitGizmoOnce(\n    PINIT_ONCE InitOnce,\n    PVOID Parameter,\n    PVOID *Context)\n{\n    Gizmo *pGizmo = reinterpret_cast&lt;Gizmo*&gt;(Parameter);\n    pGizmo-&gt;Initialize();\n    return TRUE;\n}\nSomeFunction(...)\n{\n    \/\/ Initialize ProtectedGizmo if not already initialized\n    InitOnceExecuteOnce(&amp;GizmoInitOnce,\n                        InitGizmoOnce,\n                        &amp;ProtectedGizmo,\n                        NULL);\n    \/\/ At this point, ProtectedGizmo has been initialized\n    ProtectedGizmo.Something();\n    ...\n}\n<\/pre>\n<p>\nOr you might have it protect a dynamic object:\n<\/p>\n<pre>\nclass Widget\n{\n    Widget()\n    {\n        InitOnceInitialize(&amp;m_InitOnce);\n    }\n    void Initialize();\n    ...\n    static BOOL CALLBACK InitWidgetOnce(\n        PINIT_ONCE InitOnce,\n        PVOID Parameter,\n        PVOID *Context)\n    {\n        Widget *pWidget = reinterpret_cast&lt;Widget*&gt;(Parameter);\n        pWidget-&gt;Initialize();\n        return TRUE;\n    }\n    SomeMethod(...)\n    {\n        \/\/ Initialize ourselves if not already initialized\n        InitOnceExecuteOnce(&amp;InitWidgetOnce,\n                            this,\n                            NULL);\n        \/\/ At this point, we have been initialized\n        ... some other stuff ...\n    }\n}\n<\/pre>\n<p>\nBut it so happens that you can also have the <code>INIT_ONCE<\/code>\nobject protect <i>itself<\/i>.\n<\/p>\n<p>\nYou see, once the <code>INIT_ONCE<\/code> object has entered the\n&#8220;initialization complete&#8221; state, the one-time initialization code\nonly needs a few bits of state.\nThe other bits are unused, so the kernel folks figured,\n&#8220;Well, since we&#8217;re not using them, maybe the application wants to use them.&#8221;\n<\/p>\n<p>\nThat&#8217;s where <code>INIT_ONCE_CTX_RESERVED_BITS<\/code> comes in.\nThe\n<code>INIT_ONCE_CTX_RESERVED_BITS<\/code> value is the number of bits\nthat the one-time initialization code uses after initialization is complete;\nthe other bits are free for you to use yourself.\nThe value of\n<code>INIT_ONCE_CTX_RESERVED_BITS<\/code> is 2,\nwhich means that you can store any value that&#8217;s a multiple of 4.\nIf it&#8217;s a pointer, then the pointer must be <code>DWORD<\/code>-aligned\nor better.\nThis requirement is usually easy to meet because heap-allocated objects\nsatisfy it, and the pointer you want to store is usually a pointer\nto a heap-allocated object.\nAs noted some time ago,\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2005\/01\/21\/358109.aspx\">\nkernel object handles are also multiples of four<\/a>,\nso those can also be safely stored inside the <code>INIT_ONCE<\/code>\nobject.\n(On the other hand, USER and GDI handles are <i>not<\/i> guaranteed\nto be multiples of four, so you cannot use this trick to store those\ntypes of handles.)\n<\/p>\n<p>\nHere&#8217;s an example.\nFirst, the code which uses the traditional method of having the\n<code>INIT_ONCE<\/code> structure protect another variable:\n<\/p>\n<pre>\n\/\/ using the static object pattern for simplicity\nINIT_ONCE PathInitOnce = INIT_ONCE_STATIC_INIT;\nLPWSTR PathToDatabase = NULL;\nBOOL CALLBACK InitPathOnce(\n    PINIT_ONCE InitOnce,\n    PVOID Parameter,\n    PVOID *Context)\n{\n    LPWSTR Path = (LPWSTR)LocalAlloc(LMEM_FIXED, ...);\n    if (Path == NULL) return FALSE;\n    ... get the path in Path...\n    PathToDatabase = Path;\n    return TRUE;\n}\nSomeFunction(...)\n{\n    \/\/ Get the database path (initializing if necessary)\n    if (!InitOnceExecuteOnce(&amp;PathInitOnce,\n                             InitPathOnce,\n                             NULL,\n                             NULL)) {\n        return FALSE; \/\/ couldn't get the path for some reason\n    }\n    \/\/ The \"PathToDatabase\" variable now contains the path\n    \/\/ computed by InitPathOnce.\n    OtherFunction(PathToDatabase);\n    ...\n}\n<\/pre>\n<p>\nSince the object being protected is pointer-sized and satisfies\nthe necessary alignment constraints,\nwe can merge it into the <code>INIT_ONCE<\/code> structure.\n<\/p>\n<pre>\nINIT_ONCE PathInitOnce = INIT_ONCE_STATIC_INIT;\nBOOL CALLBACK InitPathOnce(\n    PINIT_ONCE InitOnce,\n    PVOID Parameter,\n    PVOID *Context)\n{\n    LPWSTR Path = (LPWSTR)LocalAlloc(LMEM_FIXED, ...);\n    if (Path == NULL) return FALSE;\n    ... get the path in Path...\n    *Context = Path;\n    return TRUE;\n}\nSomeFunction(...)\n{\n    LPWSTR PathToDatabase;\n    \/\/ Get the database path (initializing if necessary)\n    if (!InitOnceExecuteOnce(&amp;PathInitOnce,\n                             InitPathOnce,\n                             NULL,\n                             &amp;PathToDatabase)) {\n        return FALSE; \/\/ couldn't get the path for some reason\n    }\n    \/\/ The \"PathToDatabase\" variable now contains the path\n    \/\/ computed by InitPathOnce.\n    OtherFunction(PathToDatabase);\n    ...\n}\n<\/pre>\n<p>\nThis may seem like a bunch of extra work to save four bytes\n(or eight bytes on 64-bit Windows),\nbut\nif you use the asynchronous initialization model,\nthen you have no choice but to use context-based initialization,\nas we learned when we tried to\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2011\/04\/07\/10150728.aspx\">\nwrite our own lock-free one-time initialization code<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Windows Vista adds the One-Time Initialization family of functions which address a common coding pattern: I want a specific chunk of code to run exactly once, even in the face of multiple calls from different threads. There are many implementations of this pattern, such as the infamous double-checked lock. The double-checked lock is very easy [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-7813","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Windows Vista adds the One-Time Initialization family of functions which address a common coding pattern: I want a specific chunk of code to run exactly once, even in the face of multiple calls from different threads. There are many implementations of this pattern, such as the infamous double-checked lock. The double-checked lock is very easy [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/7813","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=7813"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/7813\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=7813"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=7813"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=7813"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}