[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Berkeley DB Win32 problems.

From: <cmpilato_at_collab.net>
Date: 2001-08-22 20:37:14 CEST

Attached to this mail is a patch for one of the Sleepycat's C example
programs that, I think, demonstrates the problems we have with BDB
under Win98 (see Issue #384). Can someone please apply the patch to
db-3.2.9/examples_c/ex_env.c and make sure I've not done anything
illegal with respect to how I'm using Berkeley's API? If there are
no glaring errors in the code, I'd like to send it off to Sleepycat
with a kind "Whassup?" and see if we can nail this thing.

Note that in the patch, all I do differently is that I optionally pass
a DB_CREATE flag to db_env->open based on the non-zero-ness of the
'create' argument. Their sample used to create a DB_ENV, close it,
then remove it. With my patch, it is created, closed, and then an
attempt at re-opening it happens (which fails on my box with 'Resource
temporarily unavailable'). I'd love to hear how this behaves under
WinNT/2000, too. See svn_fs_create_berkeley() and
svn_fs_open_berkeley() for our uses of BDB in this context.

Anybody with Win32 Memory Mapped I/O experience out there? I have
none (but I'm learning). It's really weird that I can see all this
data getting written to the __db.00x files through MMIO, but it never
seems to hit the disk. Specifically, if I'm following the code right,
I'm seeing a DB_REGION In fact, I think that's the crux of the whole
problem. If I recall correctly, when trying to re-open the
environment, BDB is looking for a 'magic number' in the __db.001 file
and not finding it. I tried compiling a version of BDB with a call to
FlushViewOfFile() just before UnmapViewOfFile() but the behavior was
still the same.

Here is where the code is failing (os_win32/os_map.c:__os_map()) :

    if (is_region) {
        /*
         * XXX
         * Windows/95 zeroes anonymous memory regions at last close.
         * This means that the backing file can exist and reference
         * the region, but the region itself is no longer initialized.
         * If the caller is capable of creating the region, update
         * the REGINFO structure so that they do so.
         */
        renv = (REGENV *)pMemory;
        if (renv->magic == 0)
            if (F_ISSET(infop, REGION_CREATE_OK))
                F_SET(infop, REGION_CREATE);
            else {
                (void)UnmapViewOfFile(pMemory);
                pMemory = NULL;
                ret = EAGAIN;
            }
    }

We are trying to attach to a shared memory region, and renv->magic is
0 because the REGENV structure, which was the first thing written to
the region during the DB_ENV creation step, didn't persist (it was
never written to disk when db_env->close() was called after the
creation step). However, because the REGION_CREATE_OK flag is not set
(which, I think is because the DB_CREATE flag wasn't passed in our
"re-open" call to db_env->open()), EAGAIN is returned up the stack,
which incidentally looks something like:

    __os_map()
    __os_r_sysattach()
    __os_r_attach()
    __db_e_attach()
    db_setup()
    main()

I'm pooped, so I won't be visiting this again until at least late
tonight, but perhaps much later.

Okay, here's the patch I mentioned waaaaaaaaay up there.

--------------------------------------------------------------------------

--- ex_env.c Sat Oct 28 10:57:46 2000
+++ ex_env.c.new Wed Aug 22 12:46:20 2001
@@ -37,7 +37,7 @@
 #endif
 #endif
 
-int db_setup __P((char *, char *, FILE *, char *));
+int db_setup __P((char *, char *, FILE *, char *, int));
 int db_teardown __P((char *, char *, FILE *, char *));
 #ifdef HAVE_VXWORKS
 int ex_env __P((void));
@@ -70,9 +70,13 @@
         data_dir = CONFIG_DATA_DIR;
 
         printf("Setup env\n");
- if ((ret = db_setup(home, data_dir, stderr, progname)) != 0)
+ if ((ret = db_setup(home, data_dir, stderr, progname, 1)) != 0)
                 return (ret);
 
+ printf("Re-open env\n");
+ if ((ret = db_setup(home, data_dir, stderr, progname, 0)) != 0)
+ return (ret);
+
         printf("Teardown env\n");
         if ((ret = db_teardown(home, data_dir, stderr, progname)) != 0)
                 return (ret);
@@ -81,9 +85,10 @@
 }
 
 int
-db_setup(home, data_dir, errfp, progname)
+db_setup(home, data_dir, errfp, progname, create)
         char *home, *data_dir, *progname;
         FILE *errfp;
+ int create;
 {
         DB_ENV *dbenv;
         int ret;
@@ -122,7 +127,7 @@
 
         /* Open the environment with full transactional support. */
         if ((ret = dbenv->open(dbenv, home,
- DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN,
+ (create ? DB_CREATE : 0) | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN,
             0)) != 0) {
                 dbenv->err(dbenv, ret, "environment open: %s", home);
                 dbenv->close(dbenv, 0);

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Sat Oct 21 14:36:36 2006

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.