[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