Really (for sure this time) ensure folder opening/closing is not racy by
using the same mutex to guard the complete opening and closing processes.
* src/engine/imap-engine/imap-engine-minimal-folder.vala (MinimalFolder):
Rename open_mutex to remote_mutex since it's only actually used when
opening a remote session. Rename close_mutex to lifecycle_mutex and
ensure that has always been claimed when manipulating the
open_count. In particular, ensure that all of open_async is executed
under that mutex and ensure that both decrementing the close count, and
the complete actual closing process is always protected by it as well.
Conversation monitor was built around older assumptions of how a folder's
remote connections work - that once a folder opens it will likely also
eventually establish a remote connection, that once the connection is up
it will hang around, and so on.
This patch removes any public notion of (re)seeding, since it can't be
relied to actually happen over the course of the session, ensures that
all folder operations are local-only when the folder does not have a
working remote connection so it doesn't block, and take the opportunity
to reorganise and clean up the monitor API and documentation comments.
* src/engine/app/app-conversation-monitor.vala (ConversationMonitor):
Remove seed signals, and don't bother running an initial reseed if the
folder is already open, since the fill operation will cause any locally
incomplete messages to be filled out from the report. Manage and use an
internal Cancellable for cancelling internal operations when shutting
down. Construct a queue only when starting to monitor conversations,
delete it when stopping. Move as much operation-specific code into the
operations themselves as reasonably possible, making some methods
internal so thy can be accessed from the ops. Ensure all folder listing
operations specify LOCAL_ONLY when the remote is not open. Removed
LocalLoadOperation since that is now redundant. Update the API for
accessing conversations to match Gee conventions and update call
sites. Update documentation comments. Hook back up to locally-complete
signals so we don't miss emails being filled out by the prefetcher, for
now.
* src/engine/app/conversation-monitor/app-conversation-set.vala
(ConversationSet): Rename conversations property to match Gee
conventions, update call sites.
* src/engine/app/conversation-monitor/app-conversation-operation.vala
(ConversationOperation): Allow operations to specify if they should
allow duplicates, and allow the execution method to throw errors, so
they can be handled in a uniform way.
* src/engine/app/conversation-monitor/app-conversation-operation-queue.vala
(ConversationOperationQueue): Accept progress monitor property as a
ctor arg rather than constructing on itself, so it is tied to the
life-cycle of the ConversationMonitor rather than the queue. Add a
signal for notifying of errors thrown when running operations, and use
the new operation-independent support for determining if duplicates
should be queued.
* src/engine/app/conversation-monitor/app-fill-window-operation.vala
(FillWindowOperation): Enforce a maximum window size as well as minimum
to keep loading large windows semi-responsive. Remove code to handle
inserts now that they are handled by their own op.
* src/engine/app/conversation-monitor/app-insert-operation.vala
(InsertOperation): New operation to manage inserts, handle it them by
simply adding them to the conversation if they are newer than the
oldest message, rather that relisting all loaded messages.
Close released client sessions when there are too many, and try harder to
not give out bad sessions when one is being claimed.
* src/engine/imap/transport/imap-client-session-manager.vala
(ClientSessionManager): Add a maximum free session tunable and release
any client sessions returned if it would otherwise exceed this
threshold. When claiming a session, ensure that an older session is
still good by sending a NOOP before returning it.
This ensures that when an account synchroniser account op completes and
its folder is closing completely, that it waits for this to complete
fully. Thus when the next op executes, it can re-use the same client
session.
This, along with recent other recent changes on the branch, gets the
total client session count on app start down to 2 simultaneous
connections only, instead of 3 or 4.
* src/engine/imap-engine/imap-engine-account-synchronizer.vala
(RefreshFolderSync): If closing the folder causes it to be completely
closed, wait for that to happen so the session is released to the pool
before the next op runs.
* src/engine/imap-engine/imap-engine-minimal-folder.vala (MinimalFolder):
Make close_remote_session async so it can wait for the session to be
fully released, including returning the session to the pool. Update
call sites.
* src/engine/imap-engine/imap-engine-generic-account.vala
(GenericAccount): Make release_folder_session async so that
MinimalFolder can wait for it to be fully released, including returning
the session from Selected state. Update call sites.
* src/engine/imap-engine/imap-engine-generic-account.vala
(GenericAccount): Don't attempt to claim two client sessions when
opening a folder, rather claim one and use as both an account session
and a folder session. Rename open_folder_session to
claim_folder_session to be consistent with account session API, update
call sites.
* src/engine/imap-engine/imap-engine-minimal-folder.vala (MinimalFolder):
Ensure the remote session is automatically re-established if
appropriate on disconnect. Tidy up debug output and some comments.
For most of the time, GenericAccount does not need an open client
session, yet it always claims one from the pool on open and hangs on to
it. This means that the account synchroniser for example cannot use the
same session to perform sync, requiring an additional session to be
opened.
This patch removes the held session with methods to claim and release
account sessions instances for those code paths that need it, allowing
the previously claimed session to be re-used when not in use.
* src/engine/imap-engine/imap-engine-generic-account.vala
(GenericAccount): Remove remote_open_lock and remote_session, just
claim new client sessions from the pool as needed instead. Add
release_account_session to allow claimed sessions to be returned to the
pool. Update uses of remote_session to claim and release instead.
* src/engine/imap/transport/imap-client-session-manager.vala
(ClientSessionManager): Update ready signal to include a parameter
indicating if ready or not, so GenericAccount can still block
claim_account_session callers when not ready. Rework all code that sets
is_ready to use a common notify method that both does that and fires
the signal, and rework all code paths that stop the pool to use a
common code path that uniformly resets timers, notifies no longer
ready, and drops all client sessions.
* src/engine/imap/api/imap-account-session.vala: Remove distinction
between fetch_folder_async and fetch_folder_cached_async
since account session objects are now short-lived.
* src/client/application/geary-controller.vala (GearyController): Rather
than using several per-account maps, one for each type of related
object, introduce an AccountContext object that collects all related
objects together and use a single map from an account's info object to
the context object. When closing the controller, close each account in
the same way as it would be done if the account was closed normally, so
that the same cleanup occurs.
* src/client/components/client-web-view.vala (ClientWebView): Fix
instances being leaked due to circular ref when registering JS message
handlers.
* src/engine/util/util-idle-manager.vala,
src/engine/util/util-timeout-manager.vala: Fix instances and classes
using these being leaked due to reference loop when used with closures
as callbacks.
This splits Geary.BaseObject up into a class an interface so that classes
derived from a pre-existing, non-GLib.Object class can still use the
reference tracking infrastructure, and adds the mixin interface to a
number of key client classes such as MainWindow and ClientWebView.
* src/engine/api/geary-base-object.vala: Split Geary.BaseObject up into a
class an interface so that classed derived from a pre-existing,
non-GLib.Object class can still use the reference tracking
infrastructure.
* src/client/application/geary-application.vala (Application): Use
Application.quit to exit normally rather Gtk.main_quit so that control
is returned to the main() entry-point.
* test/engine/api/geary-email-properties-test.vala: Add new mock
EmailProperties object.
* test/engine/app/app-conversation-test.vala (ConversationTest): Set
email sent and received dates to suppress warnings adding them to
Conversation instances.
* test/engine/app/app-conversation-set-test.vala (ConversationSetTest):
Set email sent and received dates to suppress warnings adding them to
Conversation instances, handle both casees when merging two
conversations, that the first was merged to the second and vice versa.
* src/engine/app/app-conversation-monitor.vala (ConversationMonitor),
src/engine/app/conversation-monitor/app-conversation-set.vala
(ConversationSet): Don't try to add emails to a conversation if they
have no known paths - these may have been removed from the folder
between being listed and having their known paths discovered.
Now that we're not using show_all() on the main window any more, we can
safely set up the UI for both rich text editing and bcc/reply-to fields
when first constructing the composer, rather than once it has loaded and
been shown. Since we're not setting plain text mode after it's loaded,
the body is not getting modified after loading and hence not being
flagged as being non-empty.
This also stops Geary prompting to close new, blank composer, and stops it
from saving drafts for same.
* src/client/composer/composer-widget.vala (ComposerWidget): Set rich
text and extended fields action states when constructed. Set delete
quote trigger when composer content has loaded, not when the page load
has finished. Remove now redundant page-load-and-realised handler.
* src/client/composer/composer-web-view.vala (ClientWebView): Observe
rich text mode and set the appropriate class on the body when loading
it up front. Don't try to update rich text mode if the body hasn't been
loaded.
This uses the method of using present_with_time() with value instead of
Gdk.CURRENT_TIME as the arg value, as suggested in Bug 766284.
Fixes Bug 776881 under Wayland, maybe also under X11.
* src/client/application/geary-application.vala (GearyApplication),
src/client/composer/composer-container.vala (ComposerContainer):
Use workaround in present().
* src/client/application/geary-controller.vala (GearyController),
src/client/application/secret-mediator.vala (SecretMediator):
Use GearyApplication.present() instead of calling it directly on the
main window, as needed.
* src/client/composer/composer-embed.vala (ComposerEmbed): Just use the
base class's present rather that duplicating the old implementation.
Using show_all is a pita, since it causes a bunch of bugs whenever we
need to conditionally show/hide widgets. This removes all uses on the
main window in favour of either just show() or present(), and ensures
that its widgets that are shown by default, are shown by default.
* src/client/composer/composer-widget.vala (ComposerState): Remove NEW
since it doesn't actually describe a useful state and effectively is a
duplicate of PANED.
* src/client/components/client-web-view.vala (ClientWebView): Update
WebKit cache strategy used, issue a warning when a web process crashed,
not a debug message, so users might see it and know what happened. Fix
use of a number of deprecated calls.
* src/engine/imap-engine/imap-engine-minimal-folder.vala (MinimalFolder):
Split up on_update_flags into a synchronous callback and async
implementation method, pass a copy of open_cancellable to it so it's
always using the same cancellable instance and check for errors on
completion.