]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/alock.c
Plug mutex/rwlock leaks (destroy them)
[openldap] / servers / slapd / alock.c
index 461f4b556c1eeb0b32b6e7f95620c3ba610e3cb7..5fa0704105661bdf46b00516b5aa8d2cacb16f44 100644 (file)
@@ -2,7 +2,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 2005-2006 The OpenLDAP Foundation.
+ * Copyright 2005-2010 The OpenLDAP Foundation.
  * Portions Copyright 2004-2005 Symas Corporation.
  * All rights reserved.
  *
@@ -23,7 +23,9 @@
 
 #if SLAPD_BDB || SLAPD_HDB
 
+#include <lber.h>
 #include "alock.h"
+#include "lutil.h"
 
 #include <ac/stdlib.h>
 #include <ac/string.h>
@@ -32,7 +34,9 @@
 #include <ac/assert.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#ifdef HAVE_SYS_FILE_H
 #include <sys/file.h>
+#endif
 #include <fcntl.h>
 
 #ifdef _WIN32
@@ -175,7 +179,7 @@ alock_read_iattr ( unsigned char * bufptr )
        assert (bufptr != NULL);
 
        bufptr += sizeof (unsigned long int);
-       for (count=0; count <= sizeof (unsigned long int); ++count) {
+       for (count=0; count <= (int) sizeof (unsigned long int); ++count) {
                val <<= 8;
                val += (unsigned long int) *bufptr--;
        }
@@ -229,14 +233,17 @@ alock_read_slot ( alock_info_t * info,
        }
        
        if (alock_read_iattr (slotbuf) != ALOCK_MAGIC) {
-               return 1;
+               return -1;
        }
        slot_data->al_lock  = alock_read_iattr (slotbuf+8);
        slot_data->al_stamp = alock_read_iattr (slotbuf+16);
        slot_data->al_pid   = alock_read_iattr (slotbuf+24);
 
-       if (slot_data->al_appname) free (slot_data->al_appname);
-       slot_data->al_appname = calloc (1, ALOCK_MAX_APPNAME);
+       if (slot_data->al_appname) ber_memfree (slot_data->al_appname);
+       slot_data->al_appname = ber_memcalloc (1, ALOCK_MAX_APPNAME);
+       if (slot_data->al_appname == NULL) {
+               return -1;
+       }
        strncpy (slot_data->al_appname, (char *)slotbuf+32, ALOCK_MAX_APPNAME-1);
        (slot_data->al_appname) [ALOCK_MAX_APPNAME-1] = '\0';
 
@@ -262,7 +269,8 @@ alock_write_slot ( alock_info_t * info,
        alock_write_iattr (slotbuf+16, slot_data->al_stamp);
        alock_write_iattr (slotbuf+24, slot_data->al_pid);
 
-       strncpy ((char *)slotbuf+32, slot_data->al_appname, ALOCK_MAX_APPNAME-1);
+       if (slot_data->al_appname)
+               strncpy ((char *)slotbuf+32, slot_data->al_appname, ALOCK_MAX_APPNAME-1);
        slotbuf[ALOCK_SLOT_SIZE-1] = '\0';
 
        res = lseek (info->al_fd, 
@@ -299,7 +307,7 @@ alock_query_slot ( alock_info_t * info )
        (void) memset ((void *) &slot_data, 0, sizeof (alock_slot_t));
        alock_read_slot (info, &slot_data);
 
-       if (slot_data.al_appname != NULL) free (slot_data.al_appname);
+       if (slot_data.al_appname != NULL) ber_memfree (slot_data.al_appname);
        slot_data.al_appname = NULL;
 
        nosave = slot_data.al_lock & ALOCK_NOSAVE;
@@ -332,6 +340,7 @@ alock_open ( alock_info_t * info,
        char * filename;
        int res, max_slot;
        int dirty_count, live_count, nosave;
+       char *ptr;
 
        assert (info != NULL);
        assert (appname != NULL);
@@ -341,17 +350,24 @@ alock_open ( alock_info_t * info,
        slot_data.al_lock = locktype;
        slot_data.al_stamp = time(NULL);
        slot_data.al_pid = getpid();
-       slot_data.al_appname = calloc (1, ALOCK_MAX_APPNAME);
+       slot_data.al_appname = ber_memcalloc (1, ALOCK_MAX_APPNAME);
+       if (slot_data.al_appname == NULL) {
+               return ALOCK_UNSTABLE;
+       }
        strncpy (slot_data.al_appname, appname, ALOCK_MAX_APPNAME-1);
        slot_data.al_appname [ALOCK_MAX_APPNAME-1] = '\0';
 
-       filename = calloc (1, strlen (envdir) + strlen ("/alock") + 1);
-       strcpy (filename, envdir);
-       strcat (filename, "/alock");
+       filename = ber_memcalloc (1, strlen (envdir) + strlen ("/alock") + 1);
+       if (filename == NULL ) {
+               ber_memfree (slot_data.al_appname);
+               return ALOCK_UNSTABLE;
+       }
+       ptr = lutil_strcopy(filename, envdir);
+       lutil_strcopy(ptr, "/alock");
        info->al_fd = open (filename, O_CREAT|O_RDWR, 0666);
-       free (filename);
+       ber_memfree (filename);
        if (info->al_fd < 0) {
-               free (slot_data.al_appname);
+               ber_memfree (slot_data.al_appname);
                return ALOCK_UNSTABLE;
        }
        info->al_slot = 0;
@@ -359,14 +375,14 @@ alock_open ( alock_info_t * info,
        res = alock_grab_lock (info->al_fd, 0);
        if (res == -1) { 
                close (info->al_fd);
-               free (slot_data.al_appname);
+               ber_memfree (slot_data.al_appname);
                return ALOCK_UNSTABLE;
        }
 
        res = fstat (info->al_fd, &statbuf);
        if (res == -1) { 
                close (info->al_fd);
-               free (slot_data.al_appname);
+               ber_memfree (slot_data.al_appname);
                return ALOCK_UNSTABLE;
        }
 
@@ -393,9 +409,10 @@ alock_open ( alock_info_t * info,
                                ++live_count;
 
                        } else if (res == ALOCK_UNIQUE
-                               && locktype == ALOCK_UNIQUE) {
+                               && (( locktype & ALOCK_SMASK ) == ALOCK_UNIQUE
+                               || nosave )) {
                                close (info->al_fd);
-                               free (slot_data.al_appname);
+                               ber_memfree (slot_data.al_appname);
                                return ALOCK_BUSY;
 
                        } else if (res == ALOCK_DIRTY) {
@@ -403,7 +420,7 @@ alock_open ( alock_info_t * info,
 
                        } else if (res == -1) {
                                close (info->al_fd);
-                               free (slot_data.al_appname);
+                               ber_memfree (slot_data.al_appname);
                                return ALOCK_UNSTABLE;
 
                        }
@@ -412,7 +429,7 @@ alock_open ( alock_info_t * info,
 
        if (dirty_count && live_count) {
                close (info->al_fd);
-               free (slot_data.al_appname);
+               ber_memfree (slot_data.al_appname);
                return ALOCK_UNSTABLE;
        }
        
@@ -421,11 +438,11 @@ alock_open ( alock_info_t * info,
                               info->al_slot);
        if (res == -1) { 
                close (info->al_fd);
-               free (slot_data.al_appname);
+               ber_memfree (slot_data.al_appname);
                return ALOCK_UNSTABLE;
        }
        res = alock_write_slot (info, &slot_data);
-       free (slot_data.al_appname);
+       ber_memfree (slot_data.al_appname);
        if (res == -1) { 
                close (info->al_fd);
                return ALOCK_UNSTABLE;
@@ -513,7 +530,7 @@ alock_scan ( alock_info_t * info )
 }
 
 int
-alock_close ( alock_info_t * info )
+alock_close ( alock_info_t * info, int nosave )
 {
        alock_slot_t slot_data;
        int res;
@@ -534,19 +551,21 @@ alock_close ( alock_info_t * info )
        if (res == -1) {
                close (info->al_fd);
                if (slot_data.al_appname != NULL) 
-                       free (slot_data.al_appname);
+                       ber_memfree (slot_data.al_appname);
                return ALOCK_UNSTABLE;
        }
-       slot_data.al_lock = ALOCK_UNLOCKED | (slot_data.al_lock & ALOCK_NOSAVE);
+       slot_data.al_lock = ALOCK_UNLOCKED;
+       if ( nosave )
+               slot_data.al_lock |= ALOCK_NOSAVE;
        res = alock_write_slot (info, &slot_data);
        if (res == -1) {
                close (info->al_fd);
                if (slot_data.al_appname != NULL) 
-                       free (slot_data.al_appname);
+                       ber_memfree (slot_data.al_appname);
                return ALOCK_UNSTABLE;
        }
        if (slot_data.al_appname != NULL) {
-               free (slot_data.al_appname);
+               ber_memfree (slot_data.al_appname);
                slot_data.al_appname = NULL;
        }
 
@@ -618,11 +637,11 @@ alock_recover ( alock_info_t * info )
                                if (res == -1) {
                                        close (info->al_fd);
                                        if (slot_data.al_appname != NULL) 
-                                               free (slot_data.al_appname);
+                                               ber_memfree (slot_data.al_appname);
                                        return ALOCK_UNSTABLE;
                                }
                                if (slot_data.al_appname != NULL) {
-                                       free (slot_data.al_appname);
+                                       ber_memfree (slot_data.al_appname);
                                        slot_data.al_appname = NULL;
                                }