[master] 6693cfc Implement atomic creation of output files.

Lasse Karstensen lkarsten at varnish-software.com
Thu May 26 16:56:07 CEST 2016


commit 6693cfc538883dd9f5e99c186aaf78c9829e6fa0
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 dc89cb7..4c5aeac 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",
@@ -913,34 +914,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)
@@ -953,6 +957,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