You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This will eventually crash.
Note that adding the lock to vips_cache_remove() will still crash, because that will just wait until another thread releases the lock, and meanwhile the other thread may have destroyed the object.
(From GLib API documentation, it is not clear whether the whole g_signal library is thread-safe at all. And even if so, what happens if you disconnect a signal that is currently already running? Will it wait for completion? If yes, then you have just produced a deadlock, because g_signal_handler_disconnect() is called while holding the lock.)
The text was updated successfully, but these errors were encountered:
This patch makes operation cache invalidate advisory rather than
immediate. Operations set a mark on cache entries meaning "this entry is
no longer valid", then the entry is removed next time the operation
is looked up.
This breaks the loop (now the cache can remove operations, but operations
can't remove cache entries), so it should be safer (I think). Everything
is inside a mutex, at least.
see #1484
How about making invalidate advisory rather than immediate? Operations could set a mark on cache entries meaning "this entry is no longer valid", then the entry would be removed next time that operation is looked up.
This breaks the loop (now the cache can remove operations, but operations can't remove cache entries), so it should be safer (I think). Everything is inside a mutex, at least.
More generally, you're also right about signals and threading, it's a murky area.
Emit holds a ref to the object that's emitting during the process, and ref/unref is threadsafe, but that often won't be enough. Doing more than the minimum in a signal handler is asking for trouble.
Every access to
vips_cache_table
must be protected by having the mutexvips_cache_lock
locked. However, here a signal gets connected:libvips/libvips/iofuncs/cache.c
Lines 631 to 632 in 1a2a4a4
This signal will be emitted without locking
vips_cache_lock
here:libvips/libvips/iofuncs/operation.c
Line 629 in 1a2a4a4
Thus
vips_cache_remove()
gets called without the lock, however it also doesn't acquire the lock, but accessesvips_cache_table
:libvips/libvips/iofuncs/cache.c
Lines 546 to 550 in 1a2a4a4
This will eventually crash.
Note that adding the lock to
vips_cache_remove()
will still crash, because that will just wait until another thread releases the lock, and meanwhile the other thread may have destroyed the object.(From GLib API documentation, it is not clear whether the whole
g_signal
library is thread-safe at all. And even if so, what happens if you disconnect a signal that is currently already running? Will it wait for completion? If yes, then you have just produced a deadlock, becauseg_signal_handler_disconnect()
is called while holding the lock.)The text was updated successfully, but these errors were encountered: