{"id":36913,"date":"2004-12-23T06:58:00","date_gmt":"2004-12-23T06:58:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2004\/12\/23\/do-you-need-clean-up-one-shot-timers\/"},"modified":"2004-12-23T06:58:00","modified_gmt":"2004-12-23T06:58:00","slug":"do-you-need-clean-up-one-shot-timers","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20041223-00\/?p=36913","title":{"rendered":"Do you need clean up one-shot timers?"},"content":{"rendered":"<p><P>\n<A HREF=\"http:\/\/msdn.microsoft.com\/library\/en-us\/dllproc\/base\/createtimerqueuetimer.asp\">\nThe <CODE>CreateTimerQueueTimer<\/CODE> function<\/A> allows you to create\none-shot timers by passing\nthe <CODE>WT_EXECUTEONLYONCE<\/CODE> flag.\nThe documentation says that\nyou need to call\n<A HREF=\"http:\/\/msdn.microsoft.com\/library\/en-us\/dllproc\/base\/deletetimerqueuetimer.asp\">\nthe <CODE>DeleteTimerQueueTimer<\/CODE> function<\/A>\nwhen you no longer need the timer.\n<\/P>\n<P>\nWhy do you need to clean up one-shot timers?\n<\/P>\n<P>\nTo answer this, I would like to introduce you to one of my\nfavorite rhetorical questions when trying to puzzle out\nAPI design:\n&#8220;What would the world be like if this were true?&#8221;\n<\/P>\n<P>\nImagine what the world would be like if you didn&#8217;t need to\nclean up one-shot timers.\n<\/P>\n<P>\nWell, for one thing, it means that the behavior of the\nfunction would be confusing.  The caller of the\nthe <CODE>CreateTimerQueueTimer<\/CODE> function would have\nto keep track of whether the timer was one-shot or not,\nto know whether or not the handle needed to be deleted.\n<\/P>\n<P>\nBut far, far worse is that if one-shot timers were self-deleting,\nit would be impossible to use them correctly.\n<\/P>\n<P>\nSuppose you have an object that creates a one-shot timer,\nand you want to clean it up in your destructor if it hasn&#8217;t fired yet.\nIf one-shot timers were self-deleting,\nthen it would be impossible to write this object.\n<\/P>\n<PRE>\nclass Sample {\n HANDLE m_hTimer;\n Sample() : m_hTimer(NULL) { CreateTimerQueueTimer(&amp;m_hTimer, &#8230;); }\n ~Sample() { &#8230; what to write here? &#8230; }\n};\n<\/PRE>\n <P>\nYou might say, &#8220;Well, I&#8217;ll have my callback null out the\n<CODE>m_hTimer<\/CODE> variable. That way, the destructor\nwill know that the timer has fired.&#8221;\n<\/P>\n<P>\nExcept that&#8217;s a race condition.\n<\/P>\n<PRE>\nSample::Callback(void *context)\n{\n  \/\/\/ RACE WINDOW HERE\n  ((Sample*)context)-&gt;m_hTimer = NULL;\n  &#8230;\n}\n<\/PRE>\n <P>\nIf the callback is pre-empted during the race window\nand the object is destructed,\nand one-shot timers were self-deleting,\nthen the object would attempt to use an invalid handle.\n<\/P>\n<P>\nThis race window is uncloseable\nsince the race happens even before\nyou get a chance to execute a single line of code.\n<\/P>\n<P>\nSo be glad that you have to delete handles to one-shot timers.\n<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The CreateTimerQueueTimer function allows you to create one-shot timers by passing the WT_EXECUTEONLYONCE flag. The documentation says that you need to call the DeleteTimerQueueTimer function when you no longer need the timer. Why do you need to clean up one-shot timers? To answer this, I would like to introduce you to one of my favorite [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-36913","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>The CreateTimerQueueTimer function allows you to create one-shot timers by passing the WT_EXECUTEONLYONCE flag. The documentation says that you need to call the DeleteTimerQueueTimer function when you no longer need the timer. Why do you need to clean up one-shot timers? To answer this, I would like to introduce you to one of my favorite [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/36913","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=36913"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/36913\/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=36913"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=36913"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=36913"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}