On Sat, Jul 10, 2010 at 11:27:41AM -0700, Roger Binns wrote:
> On 07/10/2010 07:12 AM, Eric Smith wrote:
> > Your wrapper is nice -- have you considered folding something like it 
> > into the core (disabled by default, enabled by a compile-time flag) and 
> > submitting it to drh for official adoption?  
> 
> DRH and the developers are aware of it as my approach was discussed on one
> of the mailing lists, and I did the performance measurements in response to
> their queries.
> 
> I'd have no problem contributing the code to SQLite, but there isn't very
> much of it and it is an open issue as to how you report the cross fork usage
> should it happen.  (In my case I know Python is being used.)

Fast fork-detection logic to make the library a little more fork-safe is
a very good thing to do in all otherwise-fork-unsafe libraries.

getpid() might not be fast enough on all operating systems.  What I'd do
is make getpid() a macro like so:

#if defined(HAVE_PTHREAD_ATFORK) && defined(HAVE_WEAK_SYMBOLS)
extern pid_t my_saved_pid; /* set from a pthread_atfork(3C) child handler */
#define my_getpid() \
                (pthread_atfork == NULL ? getpid() : my_saved_pid)
#else
#ifdef NO_FORK_DETECTION
#define my_getpid() ((pid_t)-1)
#else
#define my_getpid() getpid()
#endif
#endif

/*
 * Library entry points should check whether we're forked:
 *
 *  if (FORKED(handle))
 *      return (<forked-error>);
 */
#define FORKED(handle)  ((handle->owner_pid == my_getpid()) ? 0 : 1)

This guarantees a fast getpid() no matter how slow the actual getpid()
might be, at least on modern operating systems.  Where getpid() is slow
and pthread_atfork() is not available you end up disabling fork
detection.  The result is that you end up with a tiny penalty for fork
detection: two loads, a compare and a likely-not-taken branch.

Also, where the library gets initialized, it has to set a fork child
handler with pthread_atfork(3C) if defined(HAVE_PTHREAD_ATFORK) &&
defined(HAVE_WEAK_SYMBOLS) and pthread_atfork != NULL.  The handler
would do nothing much more than my_saved_pid = getpid().  Where handles
are created, handle->owner_pid has to be set to my_getpid().

I strongly recommend this approach for all library developers.

Nico
-- 
_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to