[adwaita-icon-theme] Feed Inkscape stdin in a separate thread



commit 6b1458d521516e29ac4f3d642d0be246add379a1
Author: Руслан Ижбулатов <lrn1986 gmail com>
Date:   Thu Mar 3 08:58:18 2016 +0000

    Feed Inkscape stdin in a separate thread
    
    Writing directly into stdin of child processes from the main
    thread turned out to cause deadlocks.
    Fix this by creating a thread for each child and feeding
    its stdin from that thread. Also, instead of writing to
    stdin multiple times (for each command), compose a list of
    commands in memory and then write them all at once.
    
    Also, use EOFError exception instead of non-existing UnexpectedEndOfStream.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=763030

 src/cursors/renderpngs.py |   25 ++++++++++++++++++++-----
 1 files changed, 20 insertions(+), 5 deletions(-)
---
diff --git a/src/cursors/renderpngs.py b/src/cursors/renderpngs.py
index 6c4ba8b..6bef47e 100755
--- a/src/cursors/renderpngs.py
+++ b/src/cursors/renderpngs.py
@@ -72,12 +72,23 @@ def dbg(msg):
 
 def cleanup():
        global inkscape_instances
-       for inkscape, inkscape_stderr, inkscape_stderr_thread in inkscape_instances:
-               inkscape.communicate ('quit\n')
+       stdin_threads = []
+       for inkscape, inkscape_stderr, inkscape_stderr_thread, inkscape_stdin_buf in inkscape_instances:
+               inkscape_stdin_buf.append ('quit\n')
+               stdin_threads.append (Thread (target = stdin_writer, args=(inkscape, ''.join 
(inkscape_stdin_buf))))
+               stdin_threads[-1].start ()
+               inkscape_stderr_thread.start ()
+       for t in stdin_threads:
+               t.join ()
+               del t
+       for inkscape, inkscape_stderr, inkscape_stderr_thread, inkscape_stdin_buf in inkscape_instances:
+               inkscape_stderr_thread.join ()
                del inkscape
                del inkscape_stderr_thread
                del inkscape_stderr
+               del inkscape_stdin_buf
        del inkscape_instances
+       del stdin_threads
        if svgFilename != None and os.path.exists(svgFilename):
                os.unlink(svgFilename)
        if hotsvgFilename != None and os.path.exists(hotsvgFilename):
@@ -96,7 +107,10 @@ def stderr_reader(inkscape, inkscape_stderr):
                elif line:
                        print "STDERR> {}".format (line)
                else:
-                       raise UnexpectedEndOfStream
+                       raise EOFError
+
+def stdin_writer(inkscape, inkscape_stdin):
+       inkscape.stdin.write (inkscape_stdin)
 
 def find_hotspot (hotfile):
        img = Image.open(hotfile)
@@ -192,7 +206,7 @@ class SVGRect:
                                return
                        command = '-w {size} -h {size} --export-id="{export_id}" --export-png="{export_png}" 
{svg}\n'.format (size=size, export_id=self.name, export_png=output, svg=svgFName)
                        dbg("Command: {}".format (command))
-                       inkscape_instances[roundrobin[0]][0].stdin.write (command)
+                       inkscape_instances[roundrobin[0]][3].append (command)
 
                pngsliceFName = slicename + '.png'
                hotsliceFName = slicename + '.hotspot.png'
@@ -654,7 +668,8 @@ if __name__ == '__main__':
                        fatalError("Failed to start Inkscape shell process")
                inkscape_stderr = inkscape.stderr
                inkscape_stderr_thread = Thread (target = stderr_reader, args=(inkscape, inkscape_stderr))
-               inkscape_instances.append ([inkscape, inkscape_stderr, inkscape_stderr_thread])
+               inkscape_stdin_buf = []
+               inkscape_instances.append ([inkscape, inkscape_stderr, inkscape_stderr_thread, 
inkscape_stdin_buf])
 
        # initialise results before actually attempting to parse the SVG file
        svgBounds = SVGRect(0,0,0,0)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]