{"thread":{"id":"14521","subject":"[PATCH (GITK) 0/3] Avoid runaway processes in gitk","startedAt":"2008-07-18T05:44:48Z","lastAt":"2008-07-18T05:47:40Z","messageCount":4,"participants":["Alexander Gavrilov"],"isPatch":true,"patchVersion":1,"patchTotal":3},"messages":[{"id":"83822","messageId":"200807180944.48570.angavrilov@gmail.com","threadId":"14521","inReplyTo":null,"subject":"[PATCH (GITK) 0/3] Avoid runaway processes in gitk","fromName":"Alexander Gavrilov","fromEmail":"angavrilov@gmail.com","sentAt":"2008-07-18T05:44:48Z","receivedAt":"2008-07-18T05:44:48Z","isPatch":true,"sender":{"key":"angavrilov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/42666?v=4"},"body":"As in the 'git gui blame' case, gitk back-end processes can sometimes\nrun for a while without producing any output, e.g. diff-files on a slow\nfilesystem.\n\nThese patches make gitk explicitly kill its back-end processes.\n\nAlexander Gavrilov (3):\n      gitk: Kill back-end processes on window close.\n      gitk: Register diff-files & diff-index in commfd, to ensure kill.\n      gitk: On Windows use a Cygwin-specific flag for kill.\n\n gitk |   79 ++++++++++++++++++++++++++++++++++++++++++++---------------------\n 1 files changed, 53 insertions(+), 26 deletions(-)\n"},{"id":"83824","messageId":"200807180945.43504.angavrilov@gmail.com","threadId":"14521","inReplyTo":"200807180944.48570.angavrilov@gmail.com","subject":"[PATCH (GITK) 1/3] gitk: Kill back-end processes on window close.","fromName":"Alexander Gavrilov","fromEmail":"angavrilov@gmail.com","sentAt":"2008-07-18T05:45:43Z","receivedAt":"2008-07-18T05:45:43Z","isPatch":true,"sender":{"key":"angavrilov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/42666?v=4"},"body":"When collecting commits for a rarely changed, or recently\ncreated file or directory, rev-list may work for a noticeable\nperiod of time without producing any output. Such processes\ndon't receive SIGPIPE for a while after gitk is closed, thus\nbecoming runaway CPU hogs.\n\nSigned-off-by: Alexander Gavrilov <angavrilov@gmail.com>\n---\n gitk |   35 +++++++++++++++++++++++++----------\n 1 files changed, 25 insertions(+), 10 deletions(-)\n\ndiff --git a/gitk b/gitk\nindex fddcb45..29d79d6 100755\n--- a/gitk\n+++ b/gitk\n@@ -375,19 +375,33 @@ proc start_rev_list {view} {\n     return 1\n }\n \n+proc stop_instance {inst} {\n+    global commfd leftover\n+\n+    set fd $commfd($inst)\n+    catch {\n+\tset pid [pid $fd]\n+\texec kill $pid\n+    }\n+    catch {close $fd}\n+    nukefile $fd\n+    unset commfd($inst)\n+    unset leftover($inst)\n+}\n+\n+proc stop_backends {} {\n+    global commfd\n+\n+    foreach inst [array names commfd] {\n+\tstop_instance $inst\n+    }\n+}\n+\n proc stop_rev_list {view} {\n-    global commfd viewinstances leftover\n+    global viewinstances\n \n     foreach inst $viewinstances($view) {\n-\tset fd $commfd($inst)\n-\tcatch {\n-\t    set pid [pid $fd]\n-\t    exec kill $pid\n-\t}\n-\tcatch {close $fd}\n-\tnukefile $fd\n-\tunset commfd($inst)\n-\tunset leftover($inst)\n+\tstop_instance $inst\n     }\n     set viewinstances($view) {}\n }\n@@ -2103,6 +2117,7 @@ proc makewindow {} {\n     bind . <$M1B-minus> {incrfont -1}\n     bind . <$M1B-KP_Subtract> {incrfont -1}\n     wm protocol . WM_DELETE_WINDOW doquit\n+    bind . <Destroy> {stop_backends}\n     bind . <Button-1> \"click %W\"\n     bind $fstring <Key-Return> {dofind 1 1}\n     bind $sha1entry <Key-Return> gotocommit\n-- \n1.5.6.2.39.gd084\n"},{"id":"83825","messageId":"200807180946.43560.angavrilov@gmail.com","threadId":"14521","inReplyTo":"200807180945.43504.angavrilov@gmail.com","subject":"[PATCH (GITK) 2/3] gitk: Register diff-files & diff-index in commfd, to ensure kill.","fromName":"Alexander Gavrilov","fromEmail":"angavrilov@gmail.com","sentAt":"2008-07-18T05:46:43Z","receivedAt":"2008-07-18T05:46:43Z","isPatch":true,"sender":{"key":"angavrilov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/42666?v=4"},"body":"Local change analysis can take a noticeable amount of time on large\nfile sets, and produce no output if there are no changes. Register\nthe back-ends in commfd, so that they get properly killed on window\nclose.\n\nSigned-off-by: Alexander Gavrilov <angavrilov@gmail.com>\n---\n gitk |   39 +++++++++++++++++++++++----------------\n 1 files changed, 23 insertions(+), 16 deletions(-)\n\ndiff --git a/gitk b/gitk\nindex 29d79d6..b523c98 100755\n--- a/gitk\n+++ b/gitk\n@@ -90,6 +90,15 @@ proc dorunq {} {\n     }\n }\n \n+proc reg_instance {fd} {\n+    global commfd leftover loginstance\n+\n+    set i [incr loginstance]\n+    set commfd($i) $fd\n+    set leftover($i) {}\n+    return $i\n+}\n+\n proc unmerged_files {files} {\n     global nr_unmerged\n \n@@ -294,10 +303,10 @@ proc parseviewrevs {view revs} {\n # Start off a git log process and arrange to read its output\n proc start_rev_list {view} {\n     global startmsecs commitidx viewcomplete curview\n-    global commfd leftover tclencoding\n+    global tclencoding\n     global viewargs viewargscmd viewfiles vfilelimit\n     global showlocalchanges commitinterest\n-    global viewactive loginstance viewinstances vmergeonly\n+    global viewactive viewinstances vmergeonly\n     global pending_select mainheadid\n     global vcanopt vflags vrevs vorigargs\n \n@@ -354,10 +363,8 @@ proc start_rev_list {view} {\n \terror_popup \"[mc \"Error executing git log:\"] $err\"\n \treturn 0\n     }\n-    set i [incr loginstance]\n+    set i [reg_instance $fd]\n     set viewinstances($view) [list $i]\n-    set commfd($i) $fd\n-    set leftover($i) {}\n     if {$showlocalchanges && $mainheadid ne {}} {\n \tlappend commitinterest($mainheadid) {dodiffindex}\n     }\n@@ -420,8 +427,8 @@ proc getcommits {} {\n \n proc updatecommits {} {\n     global curview vcanopt vorigargs vfilelimit viewinstances\n-    global viewactive viewcomplete loginstance tclencoding\n-    global startmsecs commfd showneartags showlocalchanges leftover\n+    global viewactive viewcomplete tclencoding\n+    global startmsecs showneartags showlocalchanges\n     global mainheadid pending_select\n     global isworktree\n     global varcid vposids vnegids vflags vrevs\n@@ -482,10 +489,8 @@ proc updatecommits {} {\n     if {$viewactive($view) == 0} {\n \tset startmsecs [clock clicks -milliseconds]\n     }\n-    set i [incr loginstance]\n+    set i [reg_instance $fd]\n     lappend viewinstances($view) $i\n-    set commfd($i) $fd\n-    set leftover($i) {}\n     fconfigure $fd -blocking 0 -translation lf -eofchar {}\n     if {$tclencoding != {}} {\n \tfconfigure $fd -encoding $tclencoding\n@@ -4063,10 +4068,11 @@ proc dodiffindex {} {\n     incr lserial\n     set fd [open \"|git diff-index --cached HEAD\" r]\n     fconfigure $fd -blocking 0\n-    filerun $fd [list readdiffindex $fd $lserial]\n+    set i [reg_instance $fd]\n+    filerun $fd [list readdiffindex $fd $lserial $i]\n }\n \n-proc readdiffindex {fd serial} {\n+proc readdiffindex {fd serial inst} {\n     global mainheadid nullid nullid2 curview commitinfo commitdata lserial\n \n     set isdiff 1\n@@ -4077,7 +4083,7 @@ proc readdiffindex {fd serial} {\n \tset isdiff 0\n     }\n     # we only need to see one line and we don't really care what it says...\n-    close $fd\n+    stop_instance $inst\n \n     if {$serial != $lserial} {\n \treturn 0\n@@ -4086,7 +4092,8 @@ proc readdiffindex {fd serial} {\n     # now see if there are any local changes not checked in to the index\n     set fd [open \"|git diff-files\" r]\n     fconfigure $fd -blocking 0\n-    filerun $fd [list readdifffiles $fd $serial]\n+    set i [reg_instance $fd]\n+    filerun $fd [list readdifffiles $fd $serial $i]\n \n     if {$isdiff && ![commitinview $nullid2 $curview]} {\n \t# add the line for the changes in the index to the graph\n@@ -4103,7 +4110,7 @@ proc readdiffindex {fd serial} {\n     return 0\n }\n \n-proc readdifffiles {fd serial} {\n+proc readdifffiles {fd serial inst} {\n     global mainheadid nullid nullid2 curview\n     global commitinfo commitdata lserial\n \n@@ -4115,7 +4122,7 @@ proc readdifffiles {fd serial} {\n \tset isdiff 0\n     }\n     # we only need to see one line and we don't really care what it says...\n-    close $fd\n+    stop_instance $inst\n \n     if {$serial != $lserial} {\n \treturn 0\n-- \n1.5.6.2.39.gd084\n"},{"id":"83826","messageId":"200807180947.40515.angavrilov@gmail.com","threadId":"14521","inReplyTo":"200807180946.43560.angavrilov@gmail.com","subject":"[PATCH (GITK) 3/3] gitk: On Windows use a Cygwin-specific flag for kill.","fromName":"Alexander Gavrilov","fromEmail":"angavrilov@gmail.com","sentAt":"2008-07-18T05:47:40Z","receivedAt":"2008-07-18T05:47:40Z","isPatch":true,"sender":{"key":"angavrilov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/42666?v=4"},"body":"MSysGit compiles git binaries as native Windows executables,\nso they cannot be killed unless a special flag is specified.\n\nThis flag is implemented by the Cygwin version of kill,\nwhich is also included in MSysGit.\n\nSigned-off-by: Alexander Gavrilov <angavrilov@gmail.com>\n---\n gitk |    7 ++++++-\n 1 files changed, 6 insertions(+), 1 deletions(-)\n\ndiff --git a/gitk b/gitk\nindex b523c98..d7fea26 100755\n--- a/gitk\n+++ b/gitk\n@@ -388,7 +388,12 @@ proc stop_instance {inst} {\n     set fd $commfd($inst)\n     catch {\n \tset pid [pid $fd]\n-\texec kill $pid\n+\n+\tif {$::tcl_platform(platform) eq {windows}} {\n+\t    exec kill -f $pid\n+\t} else {\n+\t    exec kill $pid\n+\t}\n     }\n     catch {close $fd}\n     nukefile $fd\n-- \n1.5.6.2.39.gd084\n"}]}