[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 18:06:15 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     |   39 ++++++++++++++++++++++++++++++++++-----
 2 files changed, 39 insertions(+), 11 deletions(-)

diff --git a/framework/core.py b/framework/core.py
index 0e0aca9..ce388aa 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..e5ed612 100755
--- a/piglit-run.py
+++ b/piglit-run.py
@@ -24,11 +24,40 @@
 
 from getopt import getopt, GetoptError
 import re
-import sys
+import sys, os
 
 import framework.core as core
-
-
+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, ' '.join([str(a) for a in args]),
+		self.file.flush()
+		os.fsync(self.file.fileno())
+
+	@synchronized_self
+	def writeLine(self, *args):
+		self.write(*(args + ('\n',)))
+
+	@synchronized_self
+	def close(self):
+		self.file.close()
 
 #############################################################################
 ##### Main program
@@ -91,8 +120,8 @@ def main():
 	core.checkDir(resultsDir, False)
 
 	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.writeLine("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