{"id":3423,"date":"2013-08-23T07:00:00","date_gmt":"2013-08-23T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2013\/08\/23\/if-i-attach-a-file-to-an-existing-completion-port-do-i-have-to-close-the-completion-port-handle-a-second-time\/"},"modified":"2013-08-23T07:00:00","modified_gmt":"2013-08-23T07:00:00","slug":"if-i-attach-a-file-to-an-existing-completion-port-do-i-have-to-close-the-completion-port-handle-a-second-time","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20130823-00\/?p=3423","title":{"rendered":"If I attach a file to an existing completion port, do I have to close the completion port handle a second time?"},"content":{"rendered":"<p>\nThere are two ways of calling\n<a HREF=\"http:\/\/msdn.microsoft.com\/library\/aa363862\">\nthe\n<code>Create&shy;IO&shy;Completion&shy;Port<\/code> function<\/a>.\nYou can pass a null pointer as the\n<code>Existing&shy;Completion&shy;Port<\/code> parameter,\nindicating that you would like to create a brand new completion port,\nassociated with the file handle you passed (if you passed one).\nOr you can pass the handle of an existing completion port,\nand the file handle you passed will be associated with that port,\nin addition to whatever other file handles are already associated\nwith that port.\n<\/p>\n<p>\nIn both cases, the return value on success is a handle to the I\/O\ncompletion port,\neither the brand new one or the existing one.\nThe question from a customer was,\n&#8220;In the case where I am associating a file handle to an existing\ncompletion port,\ndo I need to close the completion port handle a second time?&#8221;\nIn other words, is there a handle leak in this code:\n<\/p>\n<pre>\nBOOL CCompletionPort::Attach(HANDLE h, ULONG_PTR key)\n{\n \/\/ you are required to have created the completion port first\n assert(m_hPort != nullptr);\n HANDLE hPort = CreateIoCompletionPort(h, m_hPort, key, 0);\n \/\/ line missing? if (hPort != nullptr) CloseHandle(hPort);\n return hPort != nullptr;\n}\n<\/pre>\n<p>\nNo, there is no handle leak.\nIf you ask to associate a file with an existing completion port,\nthe same handle you passed as the\n<code>Existing&shy;Completion&shy;Port<\/code> parameter\nis returned back on success.\nThere is no new obligation to close the handle a second time\nbecause\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2007\/08\/29\/4620336.aspx\">\nkernel handles are not reference-counted<\/a>.\nClosing a kernel handle twice is always an error,\nbecause the first close closes the handle,\nand the second close attempts to use a handle that is already closed.\nThere is no reference count on handles.&sup1;\n<\/p>\n<p>\n&sup1; There is a reference count on kernel objects, but handles are not\nreference-counted.\nThe standard way to increment the reference count on a kernel object is&#8230;\nto create a new handle to it!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>There are two ways of calling the Create&shy;IO&shy;Completion&shy;Port function. You can pass a null pointer as the Existing&shy;Completion&shy;Port parameter, indicating that you would like to create a brand new completion port, associated with the file handle you passed (if you passed one). Or you can pass the handle of an existing completion port, and the [&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-3423","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>There are two ways of calling the Create&shy;IO&shy;Completion&shy;Port function. You can pass a null pointer as the Existing&shy;Completion&shy;Port parameter, indicating that you would like to create a brand new completion port, associated with the file handle you passed (if you passed one). Or you can pass the handle of an existing completion port, and the [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/3423","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=3423"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/3423\/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=3423"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=3423"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=3423"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}