]> git.sur5r.net Git - openldap/commitdiff
Use shmat for lock region instead of mmap
authorHoward Chu <hyc@symas.com>
Tue, 28 Jun 2011 21:22:22 +0000 (14:22 -0700)
committerHoward Chu <hyc@symas.com>
Tue, 28 Jun 2011 21:22:22 +0000 (14:22 -0700)
libraries/libmdb/mdb.c

index 913de09561069bb3349dd32eb404632fde75028e..a1a2d07a831c72c07d151c26b0e28b5e7580f21c 100644 (file)
@@ -7,6 +7,8 @@
 #ifdef HAVE_SYS_FILE_H
 #include <sys/file.h>
 #endif
+#include <sys/ipc.h>
+#include <sys/shm.h>
 
 #include <assert.h>
 #include <err.h>
@@ -245,7 +247,7 @@ struct MDB_db {
 
 struct MDB_env {
        int                     me_fd;
-       int                     me_lfd;
+       key_t           me_shmkey;
 #define MDB_FIXPADDING          0x01           /* internal */
        uint32_t        me_flags;
        int                     me_maxreaders;
@@ -908,7 +910,7 @@ fail:
 }
 
 int
-mdbenv_create(MDB_env **env, size_t size)
+mdbenv_create(MDB_env **env)
 {
        MDB_env *e;
 
@@ -1022,50 +1024,40 @@ mdbenv_reader_dest(void *ptr)
 int
 mdbenv_open(MDB_env *env, const char *path, unsigned int flags, mode_t mode)
 {
-       int             oflags, rc, len;
-       char    *lpath;
-       off_t   size, rsize;
-
-       len = strlen(path);
-       lpath = malloc(len + sizeof(".lock"));
-       sprintf(lpath, "%s.lock", path);
-       if ((env->me_lfd = open(lpath, O_RDWR | O_CREAT, mode)) == -1)
+       int             oflags, rc, shmid;
+       off_t   size;
+
+
+       if (F_ISSET(flags, MDB_RDONLY))
+               oflags = O_RDONLY;
+       else
+               oflags = O_RDWR | O_CREAT | O_APPEND;
+
+       if ((env->me_fd = open(path, oflags, mode)) == -1)
                return errno;
 
-       size = lseek(env->me_lfd, 0, SEEK_END);
-       rsize = (env->me_maxreaders-1) * sizeof(MDB_reader) + sizeof(MDB_txninfo);
-       if (size < rsize) {
-               if (ftruncate(env->me_lfd, rsize) != 0) {
-                       rc = errno;
-                       close(env->me_lfd);
-                       return rc;
+       env->me_shmkey = ftok(path, 'm');
+       size = (env->me_maxreaders-1) * sizeof(MDB_reader) + sizeof(MDB_txninfo);
+       shmid = shmget(env->me_shmkey, size, IPC_CREAT|IPC_EXCL|mode);
+       if (shmid == -1) {
+               if (errno == EEXIST) {
+                       shmid = shmget(env->me_shmkey, size, IPC_CREAT|mode);
+                       if (shmid == -1)
+                               return errno;
+                       env->me_txns = shmat(shmid, NULL, 0);
+               } else {
+                       return errno;
                }
        } else {
-               rsize = size;
-               size = rsize - sizeof(MDB_txninfo);
-               env->me_maxreaders = size/sizeof(MDB_reader) + 1;
-       }
-       env->me_txns = mmap(0, rsize, PROT_READ|PROT_WRITE, MAP_SHARED,
-               env->me_lfd, 0);
-       if (env->me_txns == MAP_FAILED)
-               return errno;
-       if (size == 0) {
                pthread_mutexattr_t mattr;
 
+               env->me_txns = shmat(shmid, NULL, 0);
                pthread_mutexattr_init(&mattr);
                pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED);
                pthread_mutex_init(&env->me_txns->mt_mutex, &mattr);
                pthread_mutex_init(&env->me_txns->mt_wmutex, &mattr);
        }
 
-       if (F_ISSET(flags, MDB_RDONLY))
-               oflags = O_RDONLY;
-       else
-               oflags = O_RDWR | O_CREAT | O_APPEND;
-
-       if ((env->me_fd = open(path, oflags, mode)) == -1)
-               return errno;
-
        if ((rc = mdbenv_open2(env, flags)) != MDB_SUCCESS) {
                close(env->me_fd);
                env->me_fd = -1;
@@ -1092,10 +1084,8 @@ mdbenv_close(MDB_env *env)
        }
        close(env->me_fd);
        if (env->me_txns) {
-               size_t size = (env->me_maxreaders-1) * sizeof(MDB_reader) + sizeof(MDB_txninfo);
-               munmap(env->me_txns, size);
+               shmdt(env->me_txns);
        }
-       close(env->me_lfd);
        free(env);
 }
 
@@ -2507,8 +2497,9 @@ mdbenv_compact(MDB_env *env)
                return rc;
        }
 
-       rc = mdbenv_create(&envc, env->me_mapsize);
+       rc = mdbenv_create(&envc);
        if (rc) goto failed;
+       rc = mdbenv_set_mapsize(envc, env->me_mapsize);
 
        envc->me_fd = fd;
        rc = mdbenv_open2(envc, env->me_flags);