Patchwork [4,of,5] cmdserver: write channel header and payload by a single write() call

login
register
mail settings
Submitter Yuya Nishihara
Date Nov. 2, 2016, 12:02 p.m.
Message ID <e1a050ebbf75c6f512fe.1478088136@mimosa>
Download mbox | patch
Permalink /patch/17275/
State Accepted
Headers show

Comments

Yuya Nishihara - Nov. 2, 2016, 12:02 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1456720914 -32400
#      Mon Feb 29 13:41:54 2016 +0900
# Node ID e1a050ebbf75c6f512fe041864a1e53b647c3967
# Parent  6f7e69bc46fc158f2df39f94f6e314fc7a66eca1
# EXP-Topic stdio
cmdserver: write channel header and payload by a single write() call

This makes a channeledoutput thread-safe as long as the underlying fwrite() is
thread-safe. Both POSIX and Windows implementations are documented as MT-safe.

MT-safety is necessary to use ui.fout and ui.ferr in hgweb.

Patch

diff --git a/mercurial/commandserver.py b/mercurial/commandserver.py
--- a/mercurial/commandserver.py
+++ b/mercurial/commandserver.py
@@ -54,8 +54,8 @@  class channeledoutput(object):
     def write(self, data):
         if not data:
             return
-        self.out.write(struct.pack('>cI', self.channel, len(data)))
-        self.out.write(data)
+        # single write() to guarantee the same atomicity as the underlying file
+        self.out.write(struct.pack('>cI', self.channel, len(data)) + data)
         self.out.flush()
 
     def __getattr__(self, attr):