get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/2218870/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2218870,
    "url": "http://patchwork.ozlabs.org/api/patches/2218870/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/glibc/patch/20260401230518.317947-1-samuel.thibault@ens-lyon.org/",
    "project": {
        "id": 41,
        "url": "http://patchwork.ozlabs.org/api/projects/41/?format=api",
        "name": "GNU C Library",
        "link_name": "glibc",
        "list_id": "libc-alpha.sourceware.org",
        "list_email": "libc-alpha@sourceware.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": "",
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20260401230518.317947-1-samuel.thibault@ens-lyon.org>",
    "list_archive_url": null,
    "date": "2026-04-01T23:05:18",
    "name": "[hurd,commited] hurd: Interrupted RPC returning EINTR when server has actually changed state.",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "7074793cd3be1cea352bb7f41ec6dc126a851caf",
    "submitter": {
        "id": 418,
        "url": "http://patchwork.ozlabs.org/api/people/418/?format=api",
        "name": "Samuel Thibault",
        "email": "samuel.thibault@ens-lyon.org"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/glibc/patch/20260401230518.317947-1-samuel.thibault@ens-lyon.org/mbox/",
    "series": [
        {
            "id": 498408,
            "url": "http://patchwork.ozlabs.org/api/series/498408/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/glibc/list/?series=498408",
            "date": "2026-04-01T23:05:18",
            "name": "[hurd,commited] hurd: Interrupted RPC returning EINTR when server has actually changed state.",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/498408/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2218870/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2218870/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<libc-alpha-bounces~incoming=patchwork.ozlabs.org@sourceware.org>",
        "X-Original-To": [
            "incoming@patchwork.ozlabs.org",
            "libc-alpha@sourceware.org"
        ],
        "Delivered-To": [
            "patchwork-incoming@legolas.ozlabs.org",
            "libc-alpha@sourceware.org"
        ],
        "Authentication-Results": [
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org\n (client-ip=2620:52:6:3111::32; helo=vm01.sourceware.org;\n envelope-from=libc-alpha-bounces~incoming=patchwork.ozlabs.org@sourceware.org;\n receiver=patchwork.ozlabs.org)",
            "sourceware.org;\n dmarc=none (p=none dis=none) header.from=ens-lyon.org",
            "sourceware.org;\n spf=pass smtp.mailfrom=bounce.ens-lyon.org",
            "server2.sourceware.org;\n arc=none smtp.remote-ip=140.77.166.138"
        ],
        "Received": [
            "from vm01.sourceware.org (vm01.sourceware.org\n [IPv6:2620:52:6:3111::32])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fmLF36j6Zz1yGH\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 02 Apr 2026 10:05:43 +1100 (AEDT)",
            "from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id 986DB4BA2E36\n\tfor <incoming@patchwork.ozlabs.org>; Wed,  1 Apr 2026 23:05:41 +0000 (GMT)",
            "from sonata.ens-lyon.org (domu-toccata.ens-lyon.fr [140.77.166.138])\n by sourceware.org (Postfix) with ESMTPS id C61E04BA23C0\n for <libc-alpha@sourceware.org>; Wed,  1 Apr 2026 23:05:20 +0000 (GMT)",
            "from localhost (localhost [127.0.0.1])\n by sonata.ens-lyon.org (Postfix) with ESMTP id B29B2A47DD;\n Thu,  2 Apr 2026 01:05:19 +0200 (CEST)",
            "from sonata.ens-lyon.org ([127.0.0.1])\n by localhost (sonata.ens-lyon.org [127.0.0.1]) (amavisd-new, port 10024)\n with ESMTP id O_vyy4jr4fEn; Thu,  2 Apr 2026 01:05:19 +0200 (CEST)",
            "from end (aamiens-653-1-40-48.w83-192.abo.wanadoo.fr\n [83.192.199.48])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest\n SHA256) (No client certificate requested)\n by sonata.ens-lyon.org (Postfix) with ESMTPSA id 965E1A49DC;\n Thu,  2 Apr 2026 01:05:19 +0200 (CEST)",
            "from samy by end with local (Exim 4.99.1)\n (envelope-from <samuel.thibault@ens-lyon.org>)\n id 1w84ch-00000001KiP-0al8; Thu, 02 Apr 2026 01:05:19 +0200"
        ],
        "DKIM-Filter": [
            "OpenDKIM Filter v2.11.0 sourceware.org 986DB4BA2E36",
            "OpenDKIM Filter v2.11.0 sourceware.org C61E04BA23C0"
        ],
        "DMARC-Filter": "OpenDMARC Filter v1.4.2 sourceware.org C61E04BA23C0",
        "ARC-Filter": "OpenARC Filter v1.0.0 sourceware.org C61E04BA23C0",
        "ARC-Seal": "i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1775084720; cv=none;\n b=Z+B9W8MSM4TK1T1hUi7sm3F43/DvMXVhVCeONtG+vUZFjOqTCbw07xPPgP/dTGVhwIgM55nXVQ1YIGdc+9b4L92h8uOeWoFxaHVmG40qu/rIqwCErsXQx9k85Y4rMKJ4pgk9qIuVSSLAn3vVEhHeMUJoSqfb8ytq5p6e/FtxNek=",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1775084720; c=relaxed/simple;\n bh=i2fx8iCg8LSQiBDWl4uVCSsaEB8aa9jkB92U74Gxedg=;\n h=From:To:Subject:Date:Message-ID:MIME-Version;\n b=hJq5mI2OxoAWkS7TZWQj90CNsEqg3HtZ/REDcPa9Q2GoN0+gSg7g4s7gqUG7WLxpu4bujHwsvU43Xnq2G399vprBkYDoCUiRvv1UOKqDSQzoRn8BEgca3xq6wlb1Rtnsn6Fh6PkesiuV0GfV/Lf9iTFqhbH8fSrd+4kFihr9Cew=",
        "ARC-Authentication-Results": "i=1; server2.sourceware.org",
        "From": "Samuel Thibault <samuel.thibault@ens-lyon.org>",
        "To": "libc-alpha@sourceware.org",
        "Cc": "Mike Kelly <mike@weatherwax.co.uk>,\n\tcommit-hurd@gnu.org",
        "Subject": "[hurd,\n commited] hurd: Interrupted RPC returning EINTR when server has\n actually changed state.",
        "Date": "Thu,  2 Apr 2026 01:05:18 +0200",
        "Message-ID": "<20260401230518.317947-1-samuel.thibault@ens-lyon.org>",
        "X-Mailer": "git-send-email 2.53.0",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "X-BeenThere": "libc-alpha@sourceware.org",
        "X-Mailman-Version": "2.1.30",
        "Precedence": "list",
        "List-Id": "Libc-alpha mailing list <libc-alpha.sourceware.org>",
        "List-Unsubscribe": "<https://sourceware.org/mailman/options/libc-alpha>,\n <mailto:libc-alpha-request@sourceware.org?subject=unsubscribe>",
        "List-Archive": "<https://sourceware.org/pipermail/libc-alpha/>",
        "List-Post": "<mailto:libc-alpha@sourceware.org>",
        "List-Help": "<mailto:libc-alpha-request@sourceware.org?subject=help>",
        "List-Subscribe": "<https://sourceware.org/mailman/listinfo/libc-alpha>,\n <mailto:libc-alpha-request@sourceware.org?subject=subscribe>",
        "Errors-To": "libc-alpha-bounces~incoming=patchwork.ozlabs.org@sourceware.org"
    },
    "content": "From: Mike Kelly <mike@weatherwax.co.uk>\n\nAn interrupted RPC call can return EINTR whilst the RPC is still in\nprogress on the server. Some RPC calls have permanent consequences\n(eg. a write() to append data to a file) but a caller seeing EINTR\nshould expect that no state has changed. The signal thread now stores\nthe server's reply (which it already waited for) as the interrupted\nthread's reply.\nMessage-ID: <20260401194948.90428-3-mike@weatherwax.co.uk>\n---\n hurd/hurdsig.c | 80 ++++++++++++++++++++++++++++++++------------------\n 1 file changed, 51 insertions(+), 29 deletions(-)",
    "diff": "diff --git a/hurd/hurdsig.c b/hurd/hurdsig.c\nindex cb3e04ec0d..dda7540bae 100644\n--- a/hurd/hurdsig.c\n+++ b/hurd/hurdsig.c\n@@ -452,7 +452,7 @@ _hurdsig_abort_rpcs (struct hurd_sigstate *ss, int signo, int sigthread,\n               /* The interrupt didn't work.\n                  Destroy the receive right the thread is blocked on, and\n                  replace it with a dead name to keep the name from reuse until\n-                 the therad is done with it.  To do this atomically, first\n+                 the thread is done with it.  To do this atomically, first\n                  insert a send right, and then destroy the receive right,\n                  turning the send right into a dead name.  */\n               err = __mach_port_insert_right (__mach_task_self (),\n@@ -465,12 +465,15 @@ _hurdsig_abort_rpcs (struct hurd_sigstate *ss, int signo, int sigthread,\n             }\n \n           /* The system call return value register now contains\n-             MACH_RCV_INTERRUPTED; when mach_msg resumes, it will retry the\n-             call.  Since we have just destroyed the receive right, the retry\n-             will fail with MACH_RCV_INVALID_NAME.  Instead, just change the\n-             return value here to EINTR so mach_msg will not retry and the\n-             EINTR error code will propagate up.  */\n-          state->basic.SYSRETURN = EINTR;\n+             MACH_RCV_INTERRUPTED; when mach_msg resumes, it will\n+             retry the call.  Since we have just destroyed the receive\n+             right, the retry would fail with MACH_RCV_INVALID_NAME.\n+             Instead, just change the return value here so mach_msg\n+             will not retry. We cannot return EINTR because we do not\n+             know what state the server is in and we cannot wait for\n+             its reply. EIEIO instead indicates a fatal result for the\n+             operation. */\n+          state->basic.SYSRETURN = EIEIO;\n           *state_change = 1;\n \t}\n       else if (reply)\n@@ -479,7 +482,8 @@ _hurdsig_abort_rpcs (struct hurd_sigstate *ss, int signo, int sigthread,\n       /* All threads whose RPCs were interrupted by the interrupt_operation\n          call above will retry their RPCs unless we clear SS->intr_port.  So we\n          clear it for the thread taking a signal when SA_RESTART is clear, so\n-         that its call returns EINTR.  */\n+         that its call returns the server's response to the RPC (which includes\n+         the possibility of EINTR).  */      \n       if (! signo || !(_hurd_sigstate_actions (ss) [signo].sa_flags & SA_RESTART))\n         ss->intr_port = MACH_PORT_NULL;\n     }\n@@ -528,17 +532,8 @@ abort_all_rpcs (int signo, struct machine_thread_all_state *state, int live)\n \treply_ports[nthreads] = _hurdsig_abort_rpcs (ss, signo, 1,\n \t\t\t\t\t\t     state, &state_changed,\n \t\t\t\t\t\t     NULL);\n-\tif (live)\n+\tif (live && state_changed)\n \t  {\n-\t    if (reply_ports[nthreads] != MACH_PORT_NULL)\n-\t      {\n-\t\t/* We will wait for the reply to this RPC below, so the\n-\t\t   thread must issue a new RPC rather than waiting for the\n-\t\t   reply to the one it sent.  */\n-\t\tstate->basic.SYSRETURN = EINTR;\n-\t\tstate_changed = 1;\n-\t      }\n-\t    if (state_changed)\n \t      /* Aborting the RPC needed to change this thread's state,\n \t\t and it might ever run again.  So write back its state.  */\n \t      __thread_set_state (ss->thread, MACHINE_THREAD_STATE_FLAVOR,\n@@ -547,23 +542,50 @@ abort_all_rpcs (int signo, struct machine_thread_all_state *state, int live)\n \t  }\n       }\n \n+  /* All threads (except this one) are suspended, so _hurd_sigstates\n+     cannot have changed and therefore indexes into reply_ports still\n+     match the _hurd_sigstates sequence. */\n+  nthreads = 0;\n+\n   /* Wait for replies from all the successfully interrupted RPCs.  */\n-  while (nthreads-- > 0)\n+  for (ss = _hurd_sigstates; ss != NULL; ss = ss->next, nthreads += 1)\n     if (reply_ports[nthreads] != MACH_PORT_NULL)\n       {\n+\tmach_msg_header_t* head;\n+\tmach_port_t rcv_port;\n+\tmach_msg_option_t option;\n+\tmach_msg_timeout_t timeout;\n+\tmach_msg_size_t rcv_size;\n \terror_t err;\n-\tmach_msg_header_t head;\n-\terr = __mach_msg (&head, MACH_RCV_MSG|MACH_RCV_TIMEOUT, 0, sizeof head,\n-\t\t\t  reply_ports[nthreads],\n-\t\t\t  _hurd_interrupted_rpc_timeout, MACH_PORT_NULL);\n-\tswitch (err)\n+\n+\tmachine_get_basic_state (ss->thread, state);\n+\n+\tif (MSG_EXAMINE (&state->basic, &head, &rcv_port, &rcv_size,\n+\t\t\t &option, &timeout) == 0)\n \t  {\n-\t  case MACH_RCV_TIMED_OUT:\n-\t  case MACH_RCV_TOO_LARGE:\n-\t    break;\n+\t    assert (head != NULL && rcv_size >= sizeof(mach_msg_header_t));\n+\t    /* We use the message header/rcv_size supplied to the\n+\t       thread that initiated the RPC so that the reply is\n+\t       available to it if it resumes. */\n+\n+\t    err = __mach_msg (head, MACH_RCV_MSG|MACH_RCV_TIMEOUT, 0,\n+\t\t\t      rcv_size, reply_ports[nthreads],\n+\t\t\t      _hurd_interrupted_rpc_timeout, MACH_PORT_NULL);\n+\t  }\n+\telse\n+\t  {\n+\t    /* Faulted trying to find the RPC parameters. */\n+\t    err = EIEIO;\n+\t  }\n \n-\t  default:\n-\t    assert_perror (err);\n+\tif (live)\n+\t  {\n+\t    /* The RPC might have any result including success. The\n+\t       suspended thread must deal with the outcome. */\n+\t    state->basic.SYSRETURN = err;\n+\t    __thread_set_state (ss->thread, MACHINE_THREAD_STATE_FLAVOR,\n+\t\t\t\t(natural_t *) &state->basic,\n+\t\t\t\tMACHINE_THREAD_STATE_COUNT);\n \t  }\n       }\n }\n",
    "prefixes": [
        "hurd",
        "commited"
    ]
}