On 2017-01-30 22:21, jeremy rosen wrote:
Ok, i'm at home with a little more time on my hand.
I didn't manage to reproduce any gui blockage, though I managed to make
it very sluggish. I don't have shotwell so I did a little test script
but my tests were limited
so my first question is : What exactly do you see. Is it a complete gui
blockage, or is it just slugishness ? does the dt.gui.selection trick
make it completely responsive, or less sluggish ?
If I do nothing in the loop to yield control to the gui, the program is
by all means unresponsive. If there is some kind of response it is way
below any reasonable level of usefulness.
The dt.gui.selection trick renders the gui almost normally responsive
(there are two in-process sql queries run for each file one of which is
far less than optimal), and the progress bar updates neatly, and the
cancel button works.
I'm not completely clear how you block the gtk thread, my guess is that
you don't but that somehow some lua is called on each redraw, and when
your process is running in a secondary thread, it blocks the lua lock
which in turn blocks the gtk thread trying to run lua code.
I have no other lua scripts loaded.
calling dt.gui.selection will force lua to run some code in the "real"
gtk thread. To do that, lua programs a task to be run in the gtk thread,
release the lua lock, and wait for the job on the gtk thread to do what
it has to do. So this call not only releases the lua lock, it also
forces a task switch
a very short sleep timer will release the lua lock, but take it
immediately before the scheduler can run another thread which would take
the lock.
In fact, very short sleeps didn't do any good. It only made a
difference when the sleep approached 1000ms.
The core problem is that your main loop is a case I hadn't thought of. I
had thought of long-running shell scripts (darktable.control.execute)
waiting for some data to be availalbe on a socket or device
(darktable.control.read) or an infinite loop that sleeps for "a long
time" (darktable.control.sleep) I hadn't thought of a loop that makes
most of its processing in lua and tries to not sleep, but still need to
release the lock.
That'll be your just punishment for making the program so extensible -
you get people like me doing odd stuff :-)
could you test if replacing your call to dt.gui.selection to a call to
dt.control.execute("true") also fixes your issue ?
There is some responsiveness, but much less than with the
dt.guid.selection call. The gui is active but very sluggish and the
progress bar doesn't update smoothly any more.
if that helps, I will add a call to g_thread_yield at a strategic place
in dt.control.sleep and you will be able to call dt.control.sleep(0)
That would definitely look less obscure than the selection call.
Please let me know if there's anything I can do to help.
I've written another similar script that sets the selection in
lighttable to all missing files in the current collection.
The script logic is practically the same, it just tries to open the
files instead of looking stuff up in an sqlite db. This script doesn't
slow down or block the gui, even if I leave out calls to
dt.gui.selection or dt.control.execute.
The main difference between the two scripts is now cpu-intensive they
are. The shotwell script does loads of work on luasql, while the
missing files script just opens a file and closes it again.
I've attached the thing.
Thanks for darktable. Now I've learned how to use it a bit, I can't
imaging how I did without it.
--
René Seindal - [email protected]
____________________________________________________________________________
darktable user mailing list
to unsubscribe send a mail to [email protected]
#!/usr/bin/lua
local dt = require "darktable"
dt.configuration.check_version(...,{4,0,0})
local function printf(fmt, ...) dt.print_error(string.format(fmt, ...)) end
local function select_missing_files(images)
local selection = {};
local cancelled = false
local progress = dt.gui.create_job('Checking for missing files', true, function() cancelled = true; end)
local total = #images
printf('checking %d images for missing files', total)
progress.percent = 0;
for count, image in ipairs(images) do
local file = image.path .. '/' .. image.filename
-- printf('file %s', file)
local fp = io.open(file)
if not fp then
table.insert(selection, image)
-- printf('\tmissing')
else
io.close(fp)
end
progress.percent = count / total
-- dt.control.execute("/bin/true")
-- dt.gui.selection()
-- this function has attribute implicit_yield
-- and the progress bar updates
if cancelled then break end
end
progress.valid = false
return selection
end
dt.register_event(
"shortcut",
function(event, shortcut) return select_missing_files(dt.collection) end,
"select missing files only"
)
dt.gui.libs.select.register_selection(
"select missing",
function(event, images) return select_missing_files(images) end,
"select missing files only"
)