]> git.sur5r.net Git - openldap/commitdiff
ITS#7377 Wrap sem_wait & file locks in EINTR loops
authorHallvard Furuseth <hallvard@openldap.org>
Mon, 17 Sep 2012 13:42:14 +0000 (15:42 +0200)
committerHallvard Furuseth <hallvard@openldap.org>
Mon, 17 Sep 2012 13:42:14 +0000 (15:42 +0200)
libraries/libmdb/mdb.c

index 6b759d702aa8c11e41000e65185127424df93d2d..a593cd931475cbefe30135f23fe97fa0a6ac0e37 100644 (file)
 #define        close(fd)       CloseHandle(fd)
 #define        munmap(ptr,len) UnmapViewOfFile(ptr)
 #else
+
 #ifdef MDB_USE_POSIX_SEM
-#define LOCK_MUTEX_R(env)      sem_wait((env)->me_rmutex)
+
+#define LOCK_MUTEX_R(env)      mdb_sem_wait((env)->me_rmutex)
 #define UNLOCK_MUTEX_R(env)    sem_post((env)->me_rmutex)
-#define LOCK_MUTEX_W(env)      sem_wait((env)->me_wmutex)
+#define LOCK_MUTEX_W(env)      mdb_sem_wait((env)->me_wmutex)
 #define UNLOCK_MUTEX_W(env)    sem_post((env)->me_wmutex)
+
+static int
+mdb_sem_wait(sem_t *sem)
+{
+   int rc;
+   while ((rc = sem_wait(sem)) && (rc = errno) == EINTR) ;
+   return rc;
+}
+
 #else
        /** Lock the reader mutex.
         */
@@ -2730,10 +2741,10 @@ PIMAGE_TLS_CALLBACK mdb_tls_cbp = mdb_tls_callback;
 #endif
 
 /** Downgrade the exclusive lock on the region back to shared */
-static void
+static int
 mdb_env_share_locks(MDB_env *env)
 {
-       int toggle = mdb_env_pick_meta(env);
+       int rc = 0, toggle = mdb_env_pick_meta(env);
 
        env->me_txns->mti_txnid = env->me_metas[toggle]->mm_txnid;
 
@@ -2756,14 +2767,18 @@ mdb_env_share_locks(MDB_env *env)
                lock_info.l_whence = SEEK_SET;
                lock_info.l_start = 0;
                lock_info.l_len = 1;
-               fcntl(env->me_lfd, F_SETLK, &lock_info);
+               while ((rc = fcntl(env->me_lfd, F_SETLK, &lock_info)) &&
+                               (rc = ErrCode()) == EINTR) ;
        }
 #endif
+
+       return rc;
 }
 
 static int
 mdb_env_excl_lock(MDB_env *env, int *excl)
 {
+       int rc = 0;
 #ifdef _WIN32
        if (LockFile(env->me_lfd, 0, 0, 1, 0)) {
                *excl = 1;
@@ -2771,7 +2786,7 @@ mdb_env_excl_lock(MDB_env *env, int *excl)
                OVERLAPPED ov;
                memset(&ov, 0, sizeof(ov));
                if (!LockFileEx(env->me_lfd, 0, 0, 1, 0, &ov)) {
-                       return ErrCode();
+                       rc = ErrCode();
                }
        }
 #else
@@ -2785,12 +2800,11 @@ mdb_env_excl_lock(MDB_env *env, int *excl)
                *excl = 1;
        } else {
                lock_info.l_type = F_RDLCK;
-               if (fcntl(env->me_lfd, F_SETLKW, &lock_info)) {
-                       return ErrCode();
-               }
+               while ((rc = fcntl(env->me_lfd, F_SETLKW, &lock_info)) &&
+                               (rc = ErrCode()) == EINTR) ;
        }
 #endif
-       return 0;
+       return rc;
 }
 
 #if defined(_WIN32) || defined(MDB_USE_POSIX_SEM)
@@ -3194,8 +3208,11 @@ mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mode_t mode)
                        goto leave;
                }
 #endif
-               if (excl)
-                       mdb_env_share_locks(env);
+               if (excl) {
+                       rc = mdb_env_share_locks(env);
+                       if (rc)
+                               goto leave;
+               }
                env->me_numdbs = 2;
                env->me_dbxs = calloc(env->me_maxdbs, sizeof(MDB_dbx));
                env->me_dbflags = calloc(env->me_maxdbs, sizeof(uint16_t));