]> granicus.if.org Git - php/commitdiff
MFH:
authorMarcus Boerger <helly@php.net>
Thu, 14 Nov 2002 14:40:43 +0000 (14:40 +0000)
committerMarcus Boerger <helly@php.net>
Thu, 14 Nov 2002 14:40:43 +0000 (14:40 +0000)
Fix locking behaviour: On some systems read during write is permitted but
most libraries are not capable of that. GDBM is system dependant so there
we only test  that we do not deadlock.

ext/dba/dba.c
ext/dba/php_dba.h
ext/dba/tests/dba_cdb.phpt
ext/dba/tests/dba_db2.phpt
ext/dba/tests/dba_db3.phpt
ext/dba/tests/dba_dbm.phpt
ext/dba/tests/dba_flatfile.phpt
ext/dba/tests/dba_gdbm.phpt
ext/dba/tests/dba_handler.inc
ext/dba/tests/dba_ndbm.phpt

index dc64ef173f412b0f67f83217fd37dea3dcd036b8..126319df6b2072533ee84bdf885a285f006da831 100644 (file)
@@ -302,6 +302,31 @@ static void php_dba_update(INTERNAL_FUNCTION_PARAMETERS, int mode)
 
 #define FREENOW if(args) efree(args); if(key) efree(key)
 
+/* {{{ php_find_dbm
+ */
+dba_info *php_dba_find(const char* path TSRMLS_DC)
+{
+       list_entry *le;
+       dba_info *info;
+       int numitems, i;
+
+       numitems = zend_hash_next_free_element(&EG(regular_list));
+       for (i=1; i<numitems; i++) {
+               if (zend_hash_index_find(&EG(regular_list), i, (void **) &le)==FAILURE) {
+                       continue;
+               }
+               if (Z_TYPE_P(le) == le_db || Z_TYPE_P(le) == le_pdb) {
+                       info = (dba_info *)(le->ptr);
+                       if (!strcmp(info->path, path)) {
+                               return (dba_info *)(le->ptr);
+                       }
+               }
+       }
+
+       return NULL;
+}
+/* }}} */
+
 /* {{{ php_dba_open
  */
 static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, int persistent)
@@ -309,7 +334,7 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, int persistent)
        zval ***args = (zval ***) NULL;
        int ac = ZEND_NUM_ARGS();
        dba_mode_t modenr;
-       dba_info *info;
+       dba_info *info, *other;
        dba_handler *hptr;
        char *key = NULL, *error = NULL;
        int keylen = 0;
@@ -451,8 +476,24 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, int persistent)
        info->mode = modenr;
        info->argc = ac - 3;
        info->argv = args + 3;
+       info->flags = (hptr->flags & ~DBA_LOCK_ALL) | (lock_flag & DBA_LOCK_ALL);
+       info->lock.mode = lock_mode;
+
+       /* if any open call is a locking call:
+        * check if we already habe a locking call open that should block this call
+        * the problem is some systems would allow read during write
+        */
+       if (hptr->flags & DBA_LOCK_ALL) {
+               if ((other = php_dba_find(info->path TSRMLS_CC)) != NULL) {
+                       if (   ( (lock_mode&LOCK_EX)        && (other->lock.mode&(LOCK_EX|LOCK_SH)) )
+                           || ( (other->lock.mode&LOCK_EX) && (lock_mode&(LOCK_EX|LOCK_SH))        )
+                          ) {
+                               error = "Unable to establish lock (database file already open)"; /* force failure exit */
+                       }
+               }
+       }
 
-       if (lock_mode) {
+       if (!error && lock_mode) {
                if (lock_dbf) {
                        info->lock.name = estrdup(info->path);
                        lock_file_mode = file_mode;
index dfddfda3c42141eee6b95b9b3dc33a458b5c3fb7..2290c638e836f5821c998ea56b9de33b9a1fea5f 100644 (file)
@@ -35,6 +35,7 @@ typedef struct dba_lock {
        php_stream *fp;
        int fd;
        char *name;
+       int mode; /* LOCK_EX,LOCK_SH */
 } dba_lock;
 
 typedef struct dba_info {
@@ -47,6 +48,7 @@ typedef struct dba_info {
        int argc;
        zval ***argv;
        /* private */
+       int flags; /* whether and how dba did locking and other flags*/
        struct dba_handler *hnd;        
        dba_lock lock;
 } dba_info;
index a9afe916d8c3d0fa7463fa4c27ac5166053b0a36..2390acbce59b0142966dc8cbaeb378594fe0b7c2 100644 (file)
@@ -17,7 +17,7 @@ database handler: cdb
 3NYNYY
 Content String 2
 Content 2 replaced
-Read during write permitted
+Read during write: not allowed
 Content 2 replaced 2nd time
 The 6th value
 array(3) {
index d23700fbd6edcc207c1643ee4c11113fe13993d7..154ea32111150ebc891cda8c46c62e27693e3da7 100644 (file)
@@ -16,7 +16,7 @@ database handler: db2
 3NYNYY
 Content String 2
 Content 2 replaced
-Read during write permitted
+Read during write: not allowed
 Content 2 replaced 2nd time
 The 6th value
 array(3) {
index eea48d1b2a6ed7ee863b37d5d1ab4d962ce1ec7a..e63b2da3e1e159f34a22c090bc74dbff3ab3b6d6 100644 (file)
@@ -16,7 +16,7 @@ database handler: db3
 3NYNYY
 Content String 2
 Content 2 replaced
-Read during write permitted
+Read during write: not allowed
 Content 2 replaced 2nd time
 The 6th value
 array(3) {
index 3f4d0fcf422015085b297ba70c73149a89429c6b..937d31d0d86be24d7c981905667c278ed92a7ad0 100644 (file)
@@ -16,7 +16,7 @@ database handler: dbm
 3NYNYY
 Content String 2
 Content 2 replaced
-Read during write permitted
+Read during write: not allowed
 Content 2 replaced 2nd time
 The 6th value
 array(3) {
index 33d01809cf4f8bb02b81e6b34b9fba006aa184c7..42477dfd3c24ac4740a7473fdedf2ea90e95044b 100644 (file)
@@ -16,7 +16,7 @@ database handler: flatfile
 3NYNYY
 Content String 2
 Content 2 replaced
-Read during write permitted
+Read during write: not allowed
 Content 2 replaced 2nd time
 The 6th value
 array(3) {
index 11e267d6504680ab89ba94c58cde8931f1d4dd32..c7eb5f9978504dc91d447ee46c5252ab234b0afb 100644 (file)
@@ -11,13 +11,15 @@ DBA GDBM handler test
        $handler = 'gdbm';
        $lock_flag = ''; // lock in library
        require_once('dba_handler.inc');
+       
+       // Read during write is system dependant. Important is that there is no deadlock
 ?>
---EXPECT--
+--EXPECTF--
 database handler: gdbm
 3NYNYY
 Content String 2
 Content 2 replaced
-Read during write permitted
+Read during write:%sallowed
 Content 2 replaced 2nd time
 The 6th value
 array(3) {
index 5690075fab6b4da4282c6661820817151ced4fc3..dafc9910258b650d8116e64e79f225b91132b00c 100644 (file)
@@ -28,9 +28,9 @@
        }
        $db_writer = dba_open($db_filename, 'w'.$lock_flag, $handler);
        if (($dba_reader = @dba_open($db_filename, 'r'.$lock_flag.($lock_flag ? 't' : ''), $handler))===false) {
-               echo "Cannot read during write operation\n";
+               echo "Read during write: not allowed\n";
        } else {
-               echo "Read during write permitted\n";
+               echo "Read during write: allowed\n";
        }
        if ($db_writer!==FALSE) {
                dba_insert("key number 6", "The 6th value", $db_writer);
index 04ddfa51d04018d8489b8d03c7514964c32c6a0f..fd37b7bad2acf4a42643afbb0d987132c6eb1549 100644 (file)
@@ -16,7 +16,7 @@ database handler: ndbm
 3NYNYY
 Content String 2
 Content 2 replaced
-Read during write permitted
+Read during write: not allowed
 Content 2 replaced 2nd time
 The 6th value
 array(3) {