You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{"payload":{"commit":{"oid":"28e6a2fd6358c1b75ce2f4e7cb3fcff979dbe539","url":"/postgres/postgres/commit/28e6a2fd6358c1b75ce2f4e7cb3fcff979dbe539","authoredDate":"2019-12-09T15:03:51.000-05:00","committedDate":"2019-12-09T15:03:51.000-05:00","shortMessage":null,"shortMessageMarkdown":"\u003cdiv\u003eFix race condition in our Windows signal emulation.\u003c/div\u003e","shortMessageMarkdownLink":null,"bodyMessageHtml":"pg_signal_dispatch_thread() responded to the client (signal sender)\nand disconnected the pipe before actually setting the shared variables\nthat make the signal visible to the backend process's main thread.\nIn the worst case, it seems, effective delivery of the signal could be\npostponed for as long as the machine has any other work to do.\n\nTo fix, just move the pg_queue_signal() call so that we do it before\nresponding to the client. This essentially makes pgkill() synchronous,\nwhich is a stronger guarantee than we have on Unix. That may be\noverkill, but on the other hand we have not seen comparable timing bugs\non any Unix platform.\n\nWhile at it, add some comments to this sadly underdocumented code.\n\nProblem diagnosis and fix by Amit Kapila; I just added the comments.\n\nBack-patch to all supported versions, as it appears that this can cause\nvisible NOTIFY timing oddities on all of them, and there might be\nother misbehavior due to slow delivery of other signals.\n\nDiscussion: \u003ca href=\"https://postgr.es/m/32745.1575303812@sss.pgh.pa.us\" rel=\"nofollow\"\u003ehttps://postgr.es/m/32745.1575303812@sss.pgh.pa.us\u003c/a\u003e","authors":[{"login":"tglsfdc","displayName":"Tom Lane","avatarUrl":"https://avatars.githubusercontent.com/u/8755309?v=4","path":"/tglsfdc","isGitHub":false}],"committerAttribution":false,"committer":{"login":"tglsfdc","displayName":"Tom Lane","avatarUrl":"https://avatars.githubusercontent.com/u/8755309?v=4","path":"/tglsfdc","isGitHub":false},"parents":["99351a8b5a3882ee5d131bd37d03a67ab07b4fea"],"globalRelayId":"MDY6Q29tbWl0OTI3NDQyOjI4ZTZhMmZkNjM1OGMxYjc1Y2UyZjRlN2NiM2ZjZmY5NzlkYmU1Mzk=","sha1":"99351a8b5a3882ee5d131bd37d03a67ab07b4fea","sha2":"28e6a2fd6358c1b75ce2f4e7cb3fcff979dbe539"},"currentUser":null,"repo":{"id":927442,"defaultBranch":"master","name":"postgres","ownerLogin":"postgres","currentUserCanPush":false,"isFork":false,"isEmpty":false,"createdAt":"2010-09-21T11:35:45.000Z","ownerAvatar":"https://avatars.githubusercontent.com/u/177543?v=4","public":true,"private":false,"isOrgOwned":true},"diffEntryData":[{"diffLines":[{"stylingDirective":null,"type":"HUNK","blobLineNumber":37,"text":"@@ -38,7 +38,7 @@ static pqsigfunc pg_signal_array[PG_SIGNAL_COUNT];","html":"@@ -38,7 +38,7 @@ static pqsigfunc pg_signal_array[PG_SIGNAL_COUNT];","displayNoNewLineWarning":false,"position":0,"left":37,"right":37},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":38,"text":" static pqsigfunc pg_signal_defaults[PG_SIGNAL_COUNT];","html":" \u003cspan class=pl-k\u003estatic\u003c/span\u003e \u003cspan class=pl-smi\u003epqsigfunc\u003c/span\u003e \u003cspan class=pl-s1\u003epg_signal_defaults\u003c/span\u003e[\u003cspan class=pl-c1\u003ePG_SIGNAL_COUNT\u003c/span\u003e];","displayNoNewLineWarning":false,"position":1,"left":38,"right":38},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":39,"text":" ","html":"\u003cbr\u003e","displayNoNewLineWarning":false,"position":2,"left":39,"right":39},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":40,"text":" ","html":"\u003cbr\u003e","displayNoNewLineWarning":false,"position":3,"left":40,"right":40},{"stylingDirective":null,"type":"DELETION","blobLineNumber":41,"text":"-/* Signal handling thread function */","html":"-\u003cspan class=\"pl-c\"\u003e/* Signal handling thread \u003cspan class=\"x x-first x-last\"\u003efunction\u003c/span\u003e */\u003c/span\u003e","displayNoNewLineWarning":false,"position":4,"left":41,"right":40},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":41,"text":"+/* Signal handling thread functions */","html":"+\u003cspan class=\"pl-c\"\u003e/* Signal handling thread \u003cspan class=\"x x-first x-last\"\u003efunctions\u003c/span\u003e */\u003c/span\u003e","displayNoNewLineWarning":false,"position":5,"left":41,"right":41},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":42,"text":" static DWORD WINAPI pg_signal_thread(LPVOID param);","html":" \u003cspan class=pl-k\u003estatic\u003c/span\u003e \u003cspan class=pl-smi\u003eDWORD\u003c/span\u003e \u003cspan class=pl-c1\u003eWINAPI\u003c/span\u003e \u003cspan class=pl-en\u003epg_signal_thread\u003c/span\u003e(\u003cspan class=pl-smi\u003eLPVOID\u003c/span\u003e \u003cspan class=pl-s1\u003eparam\u003c/span\u003e);","displayNoNewLineWarning":false,"position":6,"left":42,"right":42},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":43,"text":" static BOOL WINAPI pg_console_handler(DWORD dwCtrlType);","html":" \u003cspan class=pl-k\u003estatic\u003c/span\u003e \u003cspan class=pl-smi\u003eBOOL\u003c/span\u003e \u003cspan class=pl-c1\u003eWINAPI\u003c/span\u003e \u003cspan class=pl-en\u003epg_console_handler\u003c/span\u003e(\u003cspan class=pl-smi\u003eDWORD\u003c/span\u003e \u003cspan class=pl-s1\u003edwCtrlType\u003c/span\u003e);","displayNoNewLineWarning":false,"position":7,"left":43,"right":43},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":44,"text":" ","html":"\u003cbr\u003e","displayNoNewLineWarning":false,"position":8,"left":44,"right":44},{"stylingDirective":null,"type":"HUNK","blobLineNumber":207,"text":"@@ -208,12 +208,15 @@ pgwin32_create_signal_listener(pid_t pid)","html":"@@ -208,12 +208,15 @@ pgwin32_create_signal_listener(pid_t pid)","displayNoNewLineWarning":false,"position":9,"left":207,"right":207},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":208,"text":" */","html":" \u003cspan class=pl-c\u003e */\u003c/span\u003e","displayNoNewLineWarning":false,"position":10,"left":208,"right":208},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":209,"text":" ","html":"\u003cbr\u003e","displayNoNewLineWarning":false,"position":11,"left":209,"right":209},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":210,"text":" ","html":"\u003cbr\u003e","displayNoNewLineWarning":false,"position":12,"left":210,"right":210},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":211,"text":"+/*","html":"+\u003cspan class=pl-c\u003e/*\u003c/span\u003e","displayNoNewLineWarning":false,"position":13,"left":210,"right":211},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":212,"text":"+ * Queue a signal for the main thread, by setting the flag bit and event.","html":"+\u003cspan class=pl-c\u003e * Queue a signal for the main thread, by setting the flag bit and event.\u003c/span\u003e","displayNoNewLineWarning":false,"position":14,"left":210,"right":212},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":213,"text":"+ */","html":"+\u003cspan class=pl-c\u003e */\u003c/span\u003e","displayNoNewLineWarning":false,"position":15,"left":210,"right":213},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":214,"text":" void","html":" \u003cspan class=pl-smi\u003evoid\u003c/span\u003e","displayNoNewLineWarning":false,"position":16,"left":211,"right":214},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":215,"text":" pg_queue_signal(int signum)","html":" \u003cspan class=pl-en\u003epg_queue_signal\u003c/span\u003e(\u003cspan class=pl-smi\u003eint\u003c/span\u003e \u003cspan class=pl-s1\u003esignum\u003c/span\u003e)","displayNoNewLineWarning":false,"position":17,"left":212,"right":215},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":216,"text":" {","html":" {","displayNoNewLineWarning":false,"position":18,"left":213,"right":216},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":217,"text":" \tAssert(pgwin32_signal_event != NULL);","html":" \t\u003cspan class=pl-en\u003eAssert\u003c/span\u003e(\u003cspan class=pl-s1\u003epgwin32_signal_event\u003c/span\u003e \u003cspan class=pl-c1\u003e!=\u003c/span\u003e \u003cspan class=pl-c1\u003eNULL\u003c/span\u003e);","displayNoNewLineWarning":false,"position":19,"left":214,"right":217},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":218,"text":" \tif (signum \u003e= PG_SIGNAL_COUNT || signum \u003c= 0)","html":" \t\u003cspan class=pl-k\u003eif\u003c/span\u003e (\u003cspan class=pl-s1\u003esignum\u003c/span\u003e \u0026gt;= \u003cspan class=pl-c1\u003ePG_SIGNAL_COUNT\u003c/span\u003e \u003cspan class=pl-c1\u003e||\u003c/span\u003e \u003cspan class=pl-s1\u003esignum\u003c/span\u003e \u0026lt;= \u003cspan class=pl-c1\u003e0\u003c/span\u003e)","displayNoNewLineWarning":false,"position":20,"left":215,"right":218},{"stylingDirective":null,"type":"DELETION","blobLineNumber":216,"text":"-\t\treturn;","html":"-\t\t\u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e;","displayNoNewLineWarning":false,"position":21,"left":216,"right":218},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":219,"text":"+\t\treturn;\t\t\t\t\t/* ignore any bad signal number */","html":"+\t\t\u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e;\u003cspan class=\"x x-first\"\u003e\t\t\t\t\t\u003c/span\u003e\u003cspan class=\"pl-c x x-last\"\u003e/* ignore any bad signal number */\u003c/span\u003e","displayNoNewLineWarning":false,"position":22,"left":216,"right":219},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":220,"text":" ","html":"\u003cbr\u003e","displayNoNewLineWarning":false,"position":23,"left":217,"right":220},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":221,"text":" \tEnterCriticalSection(\u0026pg_signal_crit_sec);","html":" \t\u003cspan class=pl-en\u003eEnterCriticalSection\u003c/span\u003e(\u003cspan class=pl-c1\u003e\u0026amp;\u003c/span\u003e\u003cspan class=pl-s1\u003epg_signal_crit_sec\u003c/span\u003e);","displayNoNewLineWarning":false,"position":24,"left":218,"right":221},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":222,"text":" \tpg_signal_queue |= sigmask(signum);","html":" \t\u003cspan class=pl-s1\u003epg_signal_queue\u003c/span\u003e |= \u003cspan class=pl-en\u003esigmask\u003c/span\u003e(\u003cspan class=pl-s1\u003esignum\u003c/span\u003e);","displayNoNewLineWarning":false,"position":25,"left":219,"right":222},{"stylingDirective":null,"type":"HUNK","blobLineNumber":224,"text":"@@ -222,7 +225,11 @@ pg_queue_signal(int signum)","html":"@@ -222,7 +225,11 @@ pg_queue_signal(int signum)","displayNoNewLineWarning":false,"position":26,"left":221,"right":224},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":225,"text":" \tSetEvent(pgwin32_signal_event);","html":" \t\u003cspan class=pl-en\u003eSetEvent\u003c/span\u003e(\u003cspan class=pl-s1\u003epgwin32_signal_event\u003c/span\u003e);","displayNoNewLineWarning":false,"position":27,"left":222,"right":225},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":226,"text":" }","html":" }","displayNoNewLineWarning":false,"position":28,"left":223,"right":226},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":227,"text":" ","html":"\u003cbr\u003e","displayNoNewLineWarning":false,"position":29,"left":224,"right":227},{"stylingDirective":null,"type":"DELETION","blobLineNumber":225,"text":"-/* Signal dispatching thread */","html":"-\u003cspan class=pl-c\u003e/* Signal dispatching thread */\u003c/span\u003e","displayNoNewLineWarning":false,"position":30,"left":225,"right":227},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":228,"text":"+/*","html":"+\u003cspan class=pl-c\u003e/*\u003c/span\u003e","displayNoNewLineWarning":false,"position":31,"left":225,"right":228},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":229,"text":"+ * Signal dispatching thread. This runs after we have received a named","html":"+\u003cspan class=pl-c\u003e * Signal dispatching thread. This runs after we have received a named\u003c/span\u003e","displayNoNewLineWarning":false,"position":32,"left":225,"right":229},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":230,"text":"+ * pipe connection from a client (signal sender). Process the request,","html":"+\u003cspan class=pl-c\u003e * pipe connection from a client (signal sender). Process the request,\u003c/span\u003e","displayNoNewLineWarning":false,"position":33,"left":225,"right":230},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":231,"text":"+ * close the pipe, and exit.","html":"+\u003cspan class=pl-c\u003e * close the pipe, and exit.\u003c/span\u003e","displayNoNewLineWarning":false,"position":34,"left":225,"right":231},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":232,"text":"+ */","html":"+\u003cspan class=pl-c\u003e */\u003c/span\u003e","displayNoNewLineWarning":false,"position":35,"left":225,"right":232},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":233,"text":" static DWORD WINAPI","html":" \u003cspan class=pl-k\u003estatic\u003c/span\u003e \u003cspan class=pl-smi\u003eDWORD\u003c/span\u003e \u003cspan class=pl-c1\u003eWINAPI\u003c/span\u003e","displayNoNewLineWarning":false,"position":36,"left":226,"right":233},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":234,"text":" pg_signal_dispatch_thread(LPVOID param)","html":" \u003cspan class=pl-en\u003epg_signal_dispatch_thread\u003c/span\u003e(\u003cspan class=pl-smi\u003eLPVOID\u003c/span\u003e \u003cspan class=pl-s1\u003eparam\u003c/span\u003e)","displayNoNewLineWarning":false,"position":37,"left":227,"right":234},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":235,"text":" {","html":" {","displayNoNewLineWarning":false,"position":38,"left":228,"right":235},{"stylingDirective":null,"type":"HUNK","blobLineNumber":248,"text":"@@ -242,13 +249,37 @@ pg_signal_dispatch_thread(LPVOID param)","html":"@@ -242,13 +249,37 @@ pg_signal_dispatch_thread(LPVOID param)","displayNoNewLineWarning":false,"position":39,"left":241,"right":248},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":249,"text":" \t\tCloseHandle(pipe);","html":" \t\t\u003cspan class=pl-en\u003eCloseHandle\u003c/span\u003e(\u003cspan class=pl-s1\u003epipe\u003c/span\u003e);","displayNoNewLineWarning":false,"position":40,"left":242,"right":249},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":250,"text":" \t\treturn 0;","html":" \t\t\u003cspan class=pl-k\u003ereturn\u003c/span\u003e \u003cspan class=pl-c1\u003e0\u003c/span\u003e;","displayNoNewLineWarning":false,"position":41,"left":243,"right":250},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":251,"text":" \t}","html":" \t}","displayNoNewLineWarning":false,"position":42,"left":244,"right":251},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":252,"text":"+","html":"+","displayNoNewLineWarning":false,"position":43,"left":244,"right":252},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":253,"text":"+\t/*","html":"+\t\u003cspan class=pl-c\u003e/*\u003c/span\u003e","displayNoNewLineWarning":false,"position":44,"left":244,"right":253},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":254,"text":"+\t * Queue the signal before responding to the client. In this way, it's","html":"+\u003cspan class=pl-c\u003e\t * Queue the signal before responding to the client. In this way, it\u0026#39;s\u003c/span\u003e","displayNoNewLineWarning":false,"position":45,"left":244,"right":254},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":255,"text":"+\t * guaranteed that once kill() has returned in the signal sender, the next","html":"+\u003cspan class=pl-c\u003e\t * guaranteed that once kill() has returned in the signal sender, the next\u003c/span\u003e","displayNoNewLineWarning":false,"position":46,"left":244,"right":255},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":256,"text":"+\t * CHECK_FOR_INTERRUPTS() in the signal recipient will see the signal.","html":"+\u003cspan class=pl-c\u003e\t * CHECK_FOR_INTERRUPTS() in the signal recipient will see the signal.\u003c/span\u003e","displayNoNewLineWarning":false,"position":47,"left":244,"right":256},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":257,"text":"+\t * (This is a stronger guarantee than POSIX makes; maybe we don't need it?","html":"+\u003cspan class=pl-c\u003e\t * (This is a stronger guarantee than POSIX makes; maybe we don\u0026#39;t need it?\u003c/span\u003e","displayNoNewLineWarning":false,"position":48,"left":244,"right":257},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":258,"text":"+\t * But without it, we've seen timing bugs on Windows that do not manifest","html":"+\u003cspan class=pl-c\u003e\t * But without it, we\u0026#39;ve seen timing bugs on Windows that do not manifest\u003c/span\u003e","displayNoNewLineWarning":false,"position":49,"left":244,"right":258},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":259,"text":"+\t * on any known Unix.)","html":"+\u003cspan class=pl-c\u003e\t * on any known Unix.)\u003c/span\u003e","displayNoNewLineWarning":false,"position":50,"left":244,"right":259},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":260,"text":"+\t */","html":"+\u003cspan class=pl-c\u003e\t */\u003c/span\u003e","displayNoNewLineWarning":false,"position":51,"left":244,"right":260},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":261,"text":"+\tpg_queue_signal(sigNum);","html":"+\t\u003cspan class=pl-en\u003epg_queue_signal\u003c/span\u003e(\u003cspan class=pl-s1\u003esigNum\u003c/span\u003e);","displayNoNewLineWarning":false,"position":52,"left":244,"right":261},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":262,"text":"+","html":"+","displayNoNewLineWarning":false,"position":53,"left":244,"right":262},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":263,"text":"+\t/*","html":"+\t\u003cspan class=pl-c\u003e/*\u003c/span\u003e","displayNoNewLineWarning":false,"position":54,"left":244,"right":263},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":264,"text":"+\t * Write something back to the client, allowing its CallNamedPipe() call","html":"+\u003cspan class=pl-c\u003e\t * Write something back to the client, allowing its CallNamedPipe() call\u003c/span\u003e","displayNoNewLineWarning":false,"position":55,"left":244,"right":264},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":265,"text":"+\t * to terminate.","html":"+\u003cspan class=pl-c\u003e\t * to terminate.\u003c/span\u003e","displayNoNewLineWarning":false,"position":56,"left":244,"right":265},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":266,"text":"+\t */","html":"+\u003cspan class=pl-c\u003e\t */\u003c/span\u003e","displayNoNewLineWarning":false,"position":57,"left":244,"right":266},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":267,"text":" \tWriteFile(pipe, \u0026sigNum, 1, \u0026bytes, NULL);\t/* Don't care if it works or","html":" \t\u003cspan class=pl-en\u003eWriteFile\u003c/span\u003e(\u003cspan class=pl-s1\u003epipe\u003c/span\u003e, \u003cspan class=pl-c1\u003e\u0026amp;\u003c/span\u003e\u003cspan class=pl-s1\u003esigNum\u003c/span\u003e, \u003cspan class=pl-c1\u003e1\u003c/span\u003e, \u003cspan class=pl-c1\u003e\u0026amp;\u003c/span\u003e\u003cspan class=pl-s1\u003ebytes\u003c/span\u003e, \u003cspan class=pl-c1\u003eNULL\u003c/span\u003e);\t\u003cspan class=pl-c\u003e/* Don\u0026#39;t care if it works or\u003c/span\u003e","displayNoNewLineWarning":false,"position":58,"left":245,"right":267},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":268,"text":" \t\t\t\t\t\t\t\t\t\t\t\t * not.. */","html":" \u003cspan class=pl-c\u003e\t\t\t\t\t\t\t\t\t\t\t\t * not.. */\u003c/span\u003e","displayNoNewLineWarning":false,"position":59,"left":246,"right":268},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":269,"text":"+","html":"+","displayNoNewLineWarning":false,"position":60,"left":246,"right":269},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":270,"text":"+\t/*","html":"+\t\u003cspan class=pl-c\u003e/*\u003c/span\u003e","displayNoNewLineWarning":false,"position":61,"left":246,"right":270},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":271,"text":"+\t * We must wait for the client to read the data before we can close the","html":"+\u003cspan class=pl-c\u003e\t * We must wait for the client to read the data before we can close the\u003c/span\u003e","displayNoNewLineWarning":false,"position":62,"left":246,"right":271},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":272,"text":"+\t * pipe, else the data will be lost. (If the WriteFile call failed,","html":"+\u003cspan class=pl-c\u003e\t * pipe, else the data will be lost. (If the WriteFile call failed,\u003c/span\u003e","displayNoNewLineWarning":false,"position":63,"left":246,"right":272},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":273,"text":"+\t * there'll be nothing in the buffer, so this shouldn't block.)","html":"+\u003cspan class=pl-c\u003e\t * there\u0026#39;ll be nothing in the buffer, so this shouldn\u0026#39;t block.)\u003c/span\u003e","displayNoNewLineWarning":false,"position":64,"left":246,"right":273},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":274,"text":"+\t */","html":"+\u003cspan class=pl-c\u003e\t */\u003c/span\u003e","displayNoNewLineWarning":false,"position":65,"left":246,"right":274},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":275,"text":" \tFlushFileBuffers(pipe);","html":" \t\u003cspan class=pl-en\u003eFlushFileBuffers\u003c/span\u003e(\u003cspan class=pl-s1\u003epipe\u003c/span\u003e);","displayNoNewLineWarning":false,"position":66,"left":247,"right":275},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":276,"text":"+","html":"+","displayNoNewLineWarning":false,"position":67,"left":247,"right":276},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":277,"text":"+\t/* This is a formality, since we're about to close the pipe anyway. */","html":"+\t\u003cspan class=pl-c\u003e/* This is a formality, since we\u0026#39;re about to close the pipe anyway. */\u003c/span\u003e","displayNoNewLineWarning":false,"position":68,"left":247,"right":277},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":278,"text":" \tDisconnectNamedPipe(pipe);","html":" \t\u003cspan class=pl-en\u003eDisconnectNamedPipe\u003c/span\u003e(\u003cspan class=pl-s1\u003epipe\u003c/span\u003e);","displayNoNewLineWarning":false,"position":69,"left":248,"right":278},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":279,"text":"+","html":"+","displayNoNewLineWarning":false,"position":70,"left":248,"right":279},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":280,"text":"+\t/* And we're done. */","html":"+\t\u003cspan class=pl-c\u003e/* And we\u0026#39;re done. */\u003c/span\u003e","displayNoNewLineWarning":false,"position":71,"left":248,"right":280},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":281,"text":" \tCloseHandle(pipe);","html":" \t\u003cspan class=pl-en\u003eCloseHandle\u003c/span\u003e(\u003cspan class=pl-s1\u003epipe\u003c/span\u003e);","displayNoNewLineWarning":false,"position":72,"left":249,"right":281},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":282,"text":" ","html":"\u003cbr\u003e","displayNoNewLineWarning":false,"position":73,"left":250,"right":282},{"stylingDirective":null,"type":"DELETION","blobLineNumber":251,"text":"-\tpg_queue_signal(sigNum);","html":"-\t\u003cspan class=pl-en\u003epg_queue_signal\u003c/span\u003e(\u003cspan class=pl-s1\u003esigNum\u003c/span\u003e);","displayNoNewLineWarning":false,"position":74,"left":251,"right":282},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":283,"text":" \treturn 0;","html":" \t\u003cspan class=pl-k\u003ereturn\u003c/span\u003e \u003cspan class=pl-c1\u003e0\u003c/span\u003e;","displayNoNewLineWarning":false,"position":75,"left":252,"right":283},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":284,"text":" }","html":" }","displayNoNewLineWarning":false,"position":76,"left":253,"right":284},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":285,"text":" ","html":"\u003cbr\u003e","displayNoNewLineWarning":false,"position":77,"left":254,"right":285},{"stylingDirective":null,"type":"HUNK","blobLineNumber":296,"text":"@@ -266,6 +297,7 @@ pg_signal_thread(LPVOID param)","html":"@@ -266,6 +297,7 @@ pg_signal_thread(LPVOID param)","displayNoNewLineWarning":false,"position":78,"left":265,"right":296},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":297,"text":" \t\tBOOL\t\tfConnected;","html":" \t\t\u003cspan class=pl-smi\u003eBOOL\u003c/span\u003e\t\t\u003cspan class=pl-s1\u003efConnected\u003c/span\u003e;","displayNoNewLineWarning":false,"position":79,"left":266,"right":297},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":298,"text":" \t\tHANDLE\t\thThread;","html":" \t\t\u003cspan class=pl-smi\u003eHANDLE\u003c/span\u003e\t\t\u003cspan class=pl-s1\u003ehThread\u003c/span\u003e;","displayNoNewLineWarning":false,"position":80,"left":267,"right":298},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":299,"text":" ","html":"\u003cbr\u003e","displayNoNewLineWarning":false,"position":81,"left":268,"right":299},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":300,"text":"+\t\t/* Create a new pipe instance if we don't have one. */","html":"+\t\t\u003cspan class=pl-c\u003e/* Create a new pipe instance if we don\u0026#39;t have one. */\u003c/span\u003e","displayNoNewLineWarning":false,"position":82,"left":268,"right":300},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":301,"text":" \t\tif (pipe == INVALID_HANDLE_VALUE)","html":" \t\t\u003cspan class=pl-k\u003eif\u003c/span\u003e (\u003cspan class=pl-s1\u003epipe\u003c/span\u003e \u003cspan class=pl-c1\u003e==\u003c/span\u003e \u003cspan class=pl-c1\u003eINVALID_HANDLE_VALUE\u003c/span\u003e)","displayNoNewLineWarning":false,"position":83,"left":269,"right":301},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":302,"text":" \t\t{","html":" \t\t{","displayNoNewLineWarning":false,"position":84,"left":270,"right":302},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":303,"text":" \t\t\tpipe = CreateNamedPipe(pipename, PIPE_ACCESS_DUPLEX,","html":" \t\t\t\u003cspan class=pl-s1\u003epipe\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-en\u003eCreateNamedPipe\u003c/span\u003e(\u003cspan class=pl-s1\u003epipename\u003c/span\u003e, \u003cspan class=pl-c1\u003ePIPE_ACCESS_DUPLEX\u003c/span\u003e,","displayNoNewLineWarning":false,"position":85,"left":271,"right":303},{"stylingDirective":null,"type":"HUNK","blobLineNumber":311,"text":"@@ -280,6 +312,11 @@ pg_signal_thread(LPVOID param)","html":"@@ -280,6 +312,11 @@ pg_signal_thread(LPVOID param)","displayNoNewLineWarning":false,"position":86,"left":279,"right":311},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":312,"text":" \t\t\t}","html":" \t\t\t}","displayNoNewLineWarning":false,"position":87,"left":280,"right":312},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":313,"text":" \t\t}","html":" \t\t}","displayNoNewLineWarning":false,"position":88,"left":281,"right":313},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":314,"text":" ","html":"\u003cbr\u003e","displayNoNewLineWarning":false,"position":89,"left":282,"right":314},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":315,"text":"+\t\t/*","html":"+\t\t\u003cspan class=pl-c\u003e/*\u003c/span\u003e","displayNoNewLineWarning":false,"position":90,"left":282,"right":315},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":316,"text":"+\t\t * Wait for a client to connect. If something connects before we","html":"+\u003cspan class=pl-c\u003e\t\t * Wait for a client to connect. If something connects before we\u003c/span\u003e","displayNoNewLineWarning":false,"position":91,"left":282,"right":316},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":317,"text":"+\t\t * reach here, we'll get back a \"failure\" with ERROR_PIPE_CONNECTED,","html":"+\u003cspan class=pl-c\u003e\t\t * reach here, we\u0026#39;ll get back a \u0026quot;failure\u0026quot; with ERROR_PIPE_CONNECTED,\u003c/span\u003e","displayNoNewLineWarning":false,"position":92,"left":282,"right":317},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":318,"text":"+\t\t * which is actually a success (way to go, Microsoft).","html":"+\u003cspan class=pl-c\u003e\t\t * which is actually a success (way to go, Microsoft).\u003c/span\u003e","displayNoNewLineWarning":false,"position":93,"left":282,"right":318},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":319,"text":"+\t\t */","html":"+\u003cspan class=pl-c\u003e\t\t */\u003c/span\u003e","displayNoNewLineWarning":false,"position":94,"left":282,"right":319},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":320,"text":" \t\tfConnected = ConnectNamedPipe(pipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);","html":" \t\t\u003cspan class=pl-s1\u003efConnected\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-en\u003eConnectNamedPipe\u003c/span\u003e(\u003cspan class=pl-s1\u003epipe\u003c/span\u003e, \u003cspan class=pl-c1\u003eNULL\u003c/span\u003e) ? TRUE : (\u003cspan class=pl-en\u003eGetLastError\u003c/span\u003e() \u003cspan class=pl-c1\u003e==\u003c/span\u003e \u003cspan class=pl-c1\u003eERROR_PIPE_CONNECTED\u003c/span\u003e);","displayNoNewLineWarning":false,"position":95,"left":283,"right":320},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":321,"text":" \t\tif (fConnected)","html":" \t\t\u003cspan class=pl-k\u003eif\u003c/span\u003e (\u003cspan class=pl-s1\u003efConnected\u003c/span\u003e)","displayNoNewLineWarning":false,"position":96,"left":284,"right":321},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":322,"text":" \t\t{","html":" \t\t{","displayNoNewLineWarning":false,"position":97,"left":285,"right":322}],"diffNumber":0,"diffSize":"0 Bytes","isBinary":false,"isTooBig":false,"collapsed":false,"isSubmodule":false,"lineCount":399,"linesChanged":45,"newTreeEntry":{"lineCount":399,"path":"src/backend/port/win32/signal.c","mode":100644,"isGenerated":false},"oldTreeEntry":{"lineCount":0,"path":"src/backend/port/win32/signal.c","mode":100644},"linesAdded":41,"linesDeleted":4,"path":"src/backend/port/win32/signal.c","pathDigest":"2c5f84ef39820a5225db4162994fb0f8358f462eb631aa3ba9d2b8c3ec113b75","status":"MODIFIED","truncatedReason":null,"oldOid":"99351a8b5a3882ee5d131bd37d03a67ab07b4fea","newOid":"28e6a2fd6358c1b75ce2f4e7cb3fcff979dbe539","copilotChatReference":null,"deletedSha":"99351a8b5a3882ee5d131bd37d03a67ab07b4fea","canToggleRichDiff":false,"defaultToRichDiff":false,"proseDifffHtml":null,"renderInfo":null,"dependencyDiffPath":null,"submodule":null}],"splitViewPreference":"unified","ignoreWhitespace":false,"repoOwnerGlobalRelayId":"MDEyOk9yZ2FuaXphdGlvbjE3NzU0Mw==","commentsPreference":"visible","diffLineSpacingPreference":"relaxed","useMonospaceFont":false,"pasteUrlLinkAsPlainText":false,"userNotices":[],"path":"/postgres/postgres/commit/28e6a2fd6358c1b75ce2f4e7cb3fcff979dbe539","fileTreeExpanded":true,"headerInfo":{"additions":41,"deletions":4,"filesChanged":1,"filesChangedString":"1"},"moreDiffsToLoad":false,"asyncDiffLoadInfo":{"startIndex":1,"truncated":false,"byteCount":2964,"lineShownCount":98},"commentInfo":{"canComment":false,"locked":false,"canLock":false,"repoArchived":false},"csrf_tokens":{"/users/diffview?diff=split":{"post":"NSo02xfFXvxjNggQeBGb8ugmcP-f9F_EwPRQRYmyBAGh62PU16JGGM_89sVkvFlop12OStS3q1mSt8ILbErJ1Q"},"/users/diffview?diff=unified":{"post":"lRuHlqYMs-P1OwRfGtxNu6eqAuwbg_WxOrKghA2PDA4B2tCZZmurB1nx-ooGcY8h6NH8WVDAASxo8TLK6HfB2g"},"/notifications/thread":{"post":"sFgsWGl1YbJaUH5IeqLbrRcWf0MW1uWMgJHNFEoYFHyJ92CSbQPSZ28KdfEyP3o_Vjyzuiu3r_k80rJeay8X9g"}}},"title":"Fix race condition in our Windows signal emulation. · postgres/postgres@28e6a2f","appPayload":{"helpUrl":"https://docs.github.com","findInDiffWorkerPath":"/assets-cdn/worker/find-in-diff-worker-2bfe39677d14.js","enabled_features":{"diff_ux_refresh_beta":false,"diff_inline_comments":true,"diff_ux_refresh_ssr_five":false,"diff_ux_refresh_ssr_ten":false,"react_diff_line_type_character_correction":true}}}
Fix race condition in our Windows signal emulation.
pg_signal_dispatch_thread() responded to the client (signal sender)
and disconnected the pipe before actually setting the shared variables
that make the signal visible to the backend process's main thread.
In the worst case, it seems, effective delivery of the signal could be
postponed for as long as the machine has any other work to do.
To fix, just move the pg_queue_signal() call so that we do it before
responding to the client. This essentially makes pgkill() synchronous,
which is a stronger guarantee than we have on Unix. That may be
overkill, but on the other hand we have not seen comparable timing bugs
on any Unix platform.
While at it, add some comments to this sadly underdocumented code.
Problem diagnosis and fix by Amit Kapila; I just added the comments.
Back-patch to all supported versions, as it appears that this can cause
visible NOTIFY timing oddities on all of them, and there might be
other misbehavior due to slow delivery of other signals.
Discussion: https://postgr.es/m/32745.1575303812@sss.pgh.pa.us
0 commit comments