tooltips.set_tip(madewithentry, utf8(_("Optional HTML markup to use on pages bottom for a small 'made with' label; %booh is replaced by the website of booh;\nfor example: made with <a href=%booh>booh</a>!")), nil)
src_nb_calculated_for = ''
- src_nb_thread = nil
+ src_nb_process = nil
process_src_nb = proc {
if src.text != src_nb_calculated_for
src_nb_calculated_for = src.text
- if src_nb_thread
- Thread.kill(src_nb_thread)
- src_nb_thread = nil
+ if src_nb_process
+ begin
+ Process.kill(9, src_nb_process)
+ rescue Errno::ESRCH
+ #- process doesn't exist anymore - race condition
+ end
end
if src_nb_calculated_for != '' && from_utf8_safe(src_nb_calculated_for) == ''
src_nb.set_markup(utf8(_("<span size='small'><i>invalid source directory</i></span>")))
else
if File.directory?(from_utf8_safe(src_nb_calculated_for)) && src_nb_calculated_for != '/'
if File.readable?(from_utf8_safe(src_nb_calculated_for))
- src_nb_thread = Thread.new {
- gtk_thread_protect { src_nb.set_markup(utf8(_("<span size='small'><i>processing...</i></span>"))) }
- total = { 'image' => 0, 'video' => 0, nil => 0 }
- `find '#{from_utf8_safe(src_nb_calculated_for)}' -type d -follow`.each { |dir|
- if File.basename(dir) =~ /^\./
- next
- else
- begin
- Dir.entries(dir.chomp).each { |file|
- total[entry2type(file)] += 1
- }
- rescue Errno::EACCES, Errno::ENOENT
+ rd, wr = IO.pipe
+ if src_nb_process
+ while src_nb_process
+ msg 3, "sleeping for completion of previous process"
+ sleep 0.05
+ end
+ gtk_thread_flush #- flush to avoid race condition in src_nb markup update
+ end
+ src_nb.set_markup(utf8(_("<span size='small'><i>processing...</i></span>")))
+ total = { 'image' => 0, 'video' => 0, nil => 0 }
+ if src_nb_process = fork
+ msg 3, "spawned #{src_nb_process} for #{src_nb_calculated_for}"
+ #- parent
+ wr.close
+ Thread.new {
+ rd.readlines.each { |dir|
+ if File.basename(dir) =~ /^\./
+ next
+ else
+ begin
+ Dir.entries(dir.chomp).each { |file|
+ total[entry2type(file)] += 1
+ }
+ rescue Errno::EACCES, Errno::ENOENT
+ end
end
+ }
+ rd.close
+ msg 3, "ripping #{src_nb_process}"
+ dummy, exitstatus = Process.waitpid2(src_nb_process)
+ if exitstatus == 0
+ gtk_thread_protect { src_nb.set_markup(utf8(_("<span size='small'><i>%s photos and %s videos</i></span>") % [ total['image'], total['video'] ])) }
end
+ src_nb_process = nil
}
- gtk_thread_protect { src_nb.set_markup(utf8(_("<span size='small'><i>%s photos and %s videos</i></span>") % [ total['image'], total['video'] ])) }
- src_nb_thread = nil
- }
+
+ else
+ #- child
+ rd.close
+ wr.write(`find '#{from_utf8_safe(src_nb_calculated_for)}' -type d -follow`)
+ Process.exit!(0) #- _exit
+ end
else
src_nb.set_markup(utf8(_("<span size='small'><i>permission denied</i></span>")))
end
madewith = madewithentry.text.gsub('\'', ''') #- because the parameters to booh-backend are between apostrophes
indexlink = indexlinkentry.text.gsub('\'', ''')
end
- if src_nb_thread
- Thread.kill(src_nb_thread)
+ if src_nb_process
+ begin
+ Process.kill(9, src_nb_process)
+ while src_nb_process
+ msg 3, "sleeping for completion of previous process"
+ sleep 0.05
+ end
+ rescue Errno::ESRCH
+ #- process doesn't exist
+ end
gtk_thread_flush #- needed because we're about to destroy widgets in dialog, for which they may be some pending gtk calls
end
dialog.destroy