[Piglit] [PATCH 6/7] Add SyncFileWriter for write/close synchronization on results file.

U. Artie Eoff ullysses.a.eoff at intel.com
Mon Feb 7 12:04:20 PST 2011


Add SyncFileWriter class to synchronize writes to the 'main' results
file from multiple threads.  This helps to ensure that writes to this
file are not intermingled.
---
 framework/core.py |   11 +++++------
 piglit-run.py     |   33 ++++++++++++++++++++++++++++++---
 2 files changed, 35 insertions(+), 9 deletions(-)

diff --git a/framework/core.py b/framework/core.py
index c3f757f..e51d8f3 100644
--- a/framework/core.py
+++ b/framework/core.py
@@ -123,8 +123,7 @@ class TestResult(dict):
 			else:
 				print >> result, k + ": " + encode(str(v))
 		print >> result, "!"
-		print >> file, result.getvalue(),
-
+		file.write(result.getvalue())
 
 class GroupResult(dict):
 	def __init__(self, *args):
@@ -282,9 +281,9 @@ class Environment:
 
 	def collectData(self):
 		if platform.system() != 'Windows':
-			print >>self.file, "glxinfo:", '@@@' + encode(self.run('glxinfo'))
+			self.file.write("glxinfo:", '@@@' + encode(self.run('glxinfo')), "\n")
 		if platform.system() == 'Linux':
-			print >>self.file, "lspci:", '@@@' + encode(self.run('lspci'))
+			self.file.write("lspci:", '@@@' + encode(self.run('lspci')), "\n")
 
 
 class Test:
@@ -343,7 +342,7 @@ class Test:
 			if Test.sleep:
 				time.sleep(Test.sleep)
 		else:
-			print "Dry-run: %(path)s" % locals()
+			status("dry-run")
 
 	# Returns True iff the given error message should be ignored
 	def isIgnored(self, error):
@@ -389,7 +388,7 @@ class TestProfile:
 		self.tests.doRun(env, '')
 		ThreadPools().joinAll()
 		time_end = time.time()
-		print >>env.file, "time:",(time_end-time_start)
+		env.file.write("time:", (time_end-time_start), "\n")
 
 #############################################################################
 ##### Loaders
diff --git a/piglit-run.py b/piglit-run.py
index 9f0eca6..060b17e 100755
--- a/piglit-run.py
+++ b/piglit-run.py
@@ -24,7 +24,7 @@
 
 from getopt import getopt, GetoptError
 import re
-import sys
+import sys, os
 
 import framework.core as core
 
@@ -90,9 +90,36 @@ def main():
 
 	core.checkDir(resultsDir, False)
 
+	from framework.threads import synchronized_self
+	class SyncFileWriter:
+		'''
+			Using the 'print' syntax to write to an instance of this class
+			may have unexpected results in a multithreaded program.  For example:
+				print >> file, "a", "b", "c"
+			will call write() to write "a", then call write() to write "b", and so on...
+			This type of execution allows for another thread to call write() before
+			the original statement completes its execution.
+			To avoid this behavior, call file.write() explicitly.  For example:
+				file.write("a", "b", "c", "\n")
+			will ensure that "a b c" gets written to the file before any other thread
+			is given write access.
+		'''
+		def __init__(self, filename):
+			self.file = open(filename, 'w')
+
+		@synchronized_self
+		def write(self, *args):
+			print >> self.file, args,
+			self.file.flush()
+			os.fsync(self.file.fileno())
+
+		@synchronized_self
+		def close(self):
+			self.file.close()
+
 	profile = core.loadTestProfile(profileFilename)
-	env.file = open(resultsDir + '/main', "w")
-	print >>env.file, "name: %(name)s" % { 'name': core.encode(OptionName) }
+	env.file = SyncFileWriter(resultsDir + '/main')
+	env.file.write("name: %(name)s" % { 'name': core.encode(OptionName) })
 	env.collectData()
 	profile.run(env)
 	env.file.close()
-- 
1.7.3.4



More information about the Piglit mailing list