{"id":38643,"date":"2004-06-29T07:00:00","date_gmt":"2004-06-29T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2004\/06\/29\/the-difference-between-thread-safety-and-re-entrancy\/"},"modified":"2004-06-29T07:00:00","modified_gmt":"2004-06-29T07:00:00","slug":"the-difference-between-thread-safety-and-re-entrancy","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20040629-00\/?p=38643","title":{"rendered":"The difference between thread-safety and re-entrancy"},"content":{"rendered":"<p>\nAn operation is &#8220;thread-safe&#8221; if it can be performed from multiple\nthreads safely, even if the calls happen simultaneously on multiple\nthreads.\n<\/p>\n<p>\nAn operation is re-entrant if it can be performed while the operation\nis already in progress (perhaps in another context).\nThis is a <strong>stronger<\/strong> concept than thread-safety,\nbecause the second attempt to perform the operation can even come\n<strong>from within the same thread<\/strong>.\n<\/p>\n<p>\nConsider the following function:\n<\/p>\n<pre>\nint length = 0;\nchar *s = NULL;\n\/\/ Note: Since strings end with a 0, if we want to\n\/\/ add a 0, we encode it as \"\\0\", and encode a\n\/\/ backslash as \"\\\\\".\n\/\/ WARNING! This code is buggy - do not use!\nvoid AddToString(int ch)\n{\n  EnterCriticalSection(&amp;someCriticalSection);\n  \/\/ +1 for the character we're about to add\n  \/\/ +1 for the null terminator\n  char *newString = realloc(s, (length+1) * sizeof(char));\n  if (newString) {\n    if (ch == '\\0' || ch == '\\\\') {\n      AddToString('\\\\'); \/\/ escape prefix\n    }\n    newString[length++] = ch;\n    newString[length] = '\\0';\n    s = newString;\n  }\n  LeaveCriticalSection(&amp;someCriticalSection);\n}\n<\/pre>\n<p>\nThis function is thread-safe because the critical section prevents\ntwo threads from attempting to add to the string simultaneously.\nHowever, it is not re-entrant.\n<\/p>\n<p>\nThe internal call to AddToString occurs while the data structures\nare unstable.  At the point of the call, execution re-enters\nthe start of the function AddToString, but this time the attempt\nto realloc the memory will use a pointer (s) that is no longer valid.\n(It was invalidated by the call to realloc performed by the caller.)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>An operation is &#8220;thread-safe&#8221; if it can be performed from multiple threads safely, even if the calls happen simultaneously on multiple threads. An operation is re-entrant if it can be performed while the operation is already in progress (perhaps in another context). This is a stronger concept than thread-safety, because the second attempt to perform [&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-38643","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>An operation is &#8220;thread-safe&#8221; if it can be performed from multiple threads safely, even if the calls happen simultaneously on multiple threads. An operation is re-entrant if it can be performed while the operation is already in progress (perhaps in another context). This is a stronger concept than thread-safety, because the second attempt to perform [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/38643","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=38643"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/38643\/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=38643"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=38643"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=38643"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}