[4.1] 0b1ff51 Implement atomic creation of output files.

Lasse Karstensen lkarsten at varnish-software.com
Tue Jun 14 12:58:07 CEST 2016


commit 0b1ff5170ed56484db73ee3a6396830dae01ebf5
Author: Lasse Karstensen <lkarsten at varnish-software.com>
Date:   Thu May 26 16:49:07 2016 +0200

    Implement atomic creation of output files.
    
    By writing output byte by byte, the calling parallel make would start
    jobs depending on the completed files too soon.
    
    Avoid this by writing to temporary files and move the completed results
    into place.
    
    Fixes: #1921

diff --git a/lib/libvcc/vmodtool.py b/lib/libvcc/vmodtool.py
index 2f7253a..e820c2a 100755
--- a/lib/libvcc/vmodtool.py
+++ b/lib/libvcc/vmodtool.py
@@ -41,9 +41,10 @@ import re
 import optparse
 import unittest
 import random
-from os import unlink
+from os import fdopen, rename, unlink
 from os.path import dirname, exists, join, realpath
 from pprint import pprint, pformat
+from tempfile import mkstemp
 
 ctypes = {
 	'ACL':		"VCL_ACL",
@@ -918,34 +919,37 @@ def runmain(inputvcc, rstdir, outputprefix):
 	#######################################################################
 	# Parsing done, now process
 	#
+	fd_cfile, fn_cfile = mkstemp()
+	cfile = fdopen(fd_cfile, "w")
 
-	fc = open("%s.c" % outputprefix, "w")
-	fh = open("%s.h" % outputprefix, "w")
+	fd_headerfile, fn_headerfile = mkstemp()
+	headerfile = fdopen(fd_headerfile, "w")
 
-	write_c_file_warning(fc)
-	write_c_file_warning(fh)
+	write_c_file_warning(cfile)
+	write_c_file_warning(headerfile)
 
-	fh.write('struct vmod_priv;\n\n')
+	headerfile.write('struct vmod_priv;\n\n')
 
-	fh.write('extern const struct vmod_data Vmod_%s_Data;\n\n' % vx[0].nam)
+	headerfile.write('extern const struct vmod_data Vmod_%s_Data;\n\n' % vx[0].nam)
 
-	vx[0].c_proto(fh)
+	vx[0].c_proto(headerfile)
 
-	fc.write('#include "config.h"\n')
-	fc.write('#include "vcl.h"\n')
-	fc.write('#include "vrt.h"\n')
-	fc.write('#include "%s.h"\n' % outputprefix)
-	fc.write('#include "vmod_abi.h"\n')
-	fc.write('\n')
+	cfile.write('#include "config.h"\n')
+	cfile.write('#include "vcl.h"\n')
+	cfile.write('#include "vrt.h"\n')
+	cfile.write('#include "%s.h"\n' % outputprefix)
+	cfile.write('#include "vmod_abi.h"\n')
+	cfile.write('\n')
 
-	vx[0].c_typedefs(fc)
-	vx[0].c_vmod(fc)
+	vx[0].c_typedefs(cfile)
+	vx[0].c_vmod(cfile)
 
-	fc.close()
-	fh.close()
+	cfile.close()
+	headerfile.close()
 
 	for suf in ("", ".man"):
-		fp = open(join(rstdir, "vmod_%s%s.rst" % (vx[0].nam, suf)), "w")
+		fd, fn_fp = mkstemp()
+		fp = fdopen(fd, "w")
 		write_rst_file_warning(fp)
 
 		vx[0].doc_dump(fp, suf)
@@ -958,6 +962,12 @@ def runmain(inputvcc, rstdir, outputprefix):
 			for i in copy_right:
 				fp.write("  %s\n" % i)
 			fp.write("\n")
+		fp.close()
+		rename(fn_fp, join(rstdir, "vmod_%s%s.rst" % (vx[0].nam, suf)))
+
+	# Our makefile targets the .c file so make sure to put that in place last.
+	rename(fn_headerfile, outputprefix + ".h")
+	rename(fn_cfile, outputprefix + ".h")
 
 
 if __name__ == "__main__":



More information about the varnish-commit mailing list