On 8/4/06, C. Michael Pilato <email@example.com> wrote:
> While chatting with my CollabNet cohorts on the phone a few minutes ago, and
> hearing Garrett's tales of woe regarding the recent problems found in and
> around the BDB caching code where DSO loading exists, something occurred to
> me. So, by way of background, here's a brief walk through the discussion we
> were having:
> * Garrett explains why DSO is a desirable (even cool) thing, and
> sympathizes with the stance that removing support for it is unkind.
> * The problem scenario is replayed: libsvn_fs_base is loaded, creates
> a global cache, and adds a bunch of cleanup routines to a global
> pool. Then the library is unloaded. Finally, the cleanups fire --
> only, there's no code behind them.
> * The first cut at solving this problem work for most cases, but fell
> over when accessing the FS layer via ra_local when ra_local was
> dynamically loaded.
> At this point, I was compelled to ask: "Why do we every dynamically load
> libsvn_ra_local? Or libsvn_fs_fs, for that matter?"
> Here's my proposal. Only ever dynamically load libsvn_fs_base, and
> libsvn_ra_dav, libsvn_ra_serf, on the premise that the primary reason we are
> allowing dynamic loads at all is that we want to be able to provide packages
> that are tied to externally dependent libraries like Berkeley DB, neon,
> serf, etc. A DSO-enabled package with *none* of the optional DSO's would
> still be able to use ra-local against an fsfs repository.
> Of course, with the merge-tracking folks add SQLite to the mix, maybe we
> want to continue allowing dynamic loads of libsvn_fs_fs -- that's fine with
> me. But I can't think of *any* good reason to dynamically load
> libsvn_ra_local, and am I especially proposing that we end that practice
> today, if possible. Alas, I've not looked at the code to see how difficult
> this would be.
Unfortunately, it occurred to me over lunch that we left out a key problem...
Without a global DSO pool that was created BEFORE any pool that can
have callbacks registered on it that are implemented within a DSO
loaded library we still risk having that DSO unloaded before the
callbacks are registered.
So assume that libsvn_fs is linked into the program directly, not
loaded indirectly when we load libsvn_ra_local. libsvn_fs needs to
dynamically load libsvn_fs_base. The process goes like this:
0) apr_initialize is called
1) We create an application pool
2) We call into libsvn_fs to open a bdb backed repos
3) libsvn_fs creates a global pool to hold DSOs
4) libsvn_fs opens libsvn_fs_base in that pool
5) We return an svn_fs_t allocated in the application pool.
6) The program completes and exits
7) apr_terminate is called
8) The libsvn_fs global pool was created second, so it's destroyed first
9) This unloads libsvn_fs_base
10) The application pool is destroyed and tries to call the callback
defined in libsvn_fs_base
This is the same problem Brane pointed out, and AFAICT regardless of
what libraries are linked in directly we still have this problem as
long as any DSO is unloaded prior to any other pool being destroyed.
To unsubscribe, e-mail: firstname.lastname@example.org
For additional commands, e-mail: email@example.com
Received on Fri Aug 4 19:15:40 2006