gecko-dev/xpcom
Gijs Kruitbosch af2df0c8a7 Bug 1614795 - use the background task queue for startupcache writes, r=dthayer,decoder
Prior to this patch, the startupcache created its own mWriteThread off which it
wrote to disk. It's initialized by MaybeSpawnWriteThread, which got called
at shutdown, to do the shutdown write if there was any reason to do so, and
from a timer that is re-initialized after every addition to the startup cache,
to run 60s after the last change to the cache.

It then joined that write thread on the main thread (in other words, blocks
on that off-main-thread write completing from the main thread) when:
- xpcom-shutdown fired
- the startupcache itself gets destroyed
- someone calls any of:
  * HasEntry
  * GetBuffer
  * PutBuffer
  * InvalidateCache

This patch removes the separate write thread, and instead dispatches a task to
the background task queue, indicating it can block. The task is started in
the same circumstances where we previously used to write (timer from the last
PutBuffer call, and shutdown if necessary).

To ensure it cannot be trying to use the data it writes out (mTable) from
the other thread while that data changes on the main thread, we use a mutex.
The task locks the mutex before starting, and unlocks when finished.
Enumerating the cases that we used to block on joining the thread:

In terms of application shutdown, we expect the background task queue to
either finish the write task, or fail to run it if it hasn't started it yet.
In the FastStartup case, we check if a write was necessary; if so, we
attempt to gain the lock without waiting. If we're successful, the write has
not yet started, and we instead run the write on the main thread. Otherwise,
we retry gaining the lock, blocking this time, thus guaranteeing the
off-the-main-thread write completes.

The task keeps a reference to the startupcache object, so it cannot be
destroyed while the task is pending.

Because the write does not modify `mTable`, and neither does `HasEntry`,
we do not need to do anything there.

In the `GetBuffer` case, we do not modify the table unless we have to read
the entry off disk (memmapped into `mCacheData`). This can only happen if
`mCacheData.initialized()` returns true, and we specifically call
`mCacheData.reset()` before firing off the write task to avoid this.
`mCacheData` is only re-initialized if someone calls `LoadArchive()`,
which can only happen from `Init()` (which is guaranteed not to run
again because this is a singleton), or `InvalidateCache()`, where we lock
the mutex (see below). So this is safe - but we assert on the lock to try
and avoid people breaking this chain of assumptions in the future.

When `PutBuffer` is called, we try to lock the mutex - but if locking fails
(ie the background thread is writing), we simply fail to store the entry
in the startupcache. In practice, this should be rare - it'd happen if
new calls to PutBuffer happen while writing during shutdown (when really,
we don't care) or when it's been 60 seconds since the last PutBuffer so
we started writing the startupcache.

When InvalidateCache is called, we lock the mutex - we shouldn't try to
write while invalidating, or invalidate while writing. This may be slow,
but in practice nothing should call `InvalidateCache` except developer
restarts or the `-purgecaches` commandline flag, so it shouldn't
matter a great deal.

Differential Revision: https://phabricator.services.mozilla.com/D70413

--HG--
extra : moz-landing-system : lando
2020-04-15 20:43:44 +00:00
..
base Bug 1614795 - use the background task queue for startupcache writes, r=dthayer,decoder 2020-04-15 20:43:44 +00:00
build Bug 1496578 - convert nsDefaultURIFixup to URIFixup.jsm. r=Gijs,farre 2020-04-08 11:30:14 +00:00
components Update configs. IGNORE BROKEN CHANGESETS CLOSED TREE NO BUG a=release ba=release 2020-04-06 14:28:50 +00:00
doc
ds Bug 1628954 - Don't use 'is' and 'is not' to perform comparison against strings in Python r=nalexander 2020-04-15 17:03:05 +00:00
glue Bug 1568994 - Add Update URL template to application.ini, XREAppData, and Services.appinfo r=glandium 2020-03-26 00:57:13 +00:00
idl-parser Bug 1621452 - Generate xpidllex.py and xpidlyacc.py with python2. r=rstewart 2020-03-18 23:53:17 +00:00
io Bug 1595886 - Use a temp string in readSegments r=dragana 2020-04-15 12:31:34 +00:00
libxpt/xptcall
reflect Bug 1625138 - Part 41: Remove no longer needed includes for mozilla/TypeTraits. r=froydnj 2020-03-28 16:00:09 +00:00
rust Bug 1625286 - Expose dispatch flags to `moz_task`. r=KrisWright 2020-03-30 19:24:08 +00:00
string Bug 1432749 - Part 1: Add DefaultHasher for nsTString. r=smaug 2020-04-14 06:00:05 +00:00
system Bug 1621116: Make the version and build ID of the previous instance of Firefox to use the current profile available. r=froydnj,glandium 2020-04-07 08:23:32 +00:00
tests Bug 1627393 - Add missing includes and namespaces to xpcom/tests. r=xpcom-reviewers,sg 2020-04-07 19:10:57 +00:00
threads Bug 1627935 - PrioritizedEventQueue::GetEvent doesn't return the correct priority value, r=bas 2020-04-13 22:22:57 +00:00
windbgdlg
xpidl
moz.build
xpcom-config.h.in Bug 1570982 - remove `CPP_THROW_NEW`; r=glandium 2019-08-14 01:32:41 +00:00
xpcom-private.h.in