roger@mav.com (Roger Droz) (05/07/91)
[Apologies if I'm bugging the net about a long-since fixed problem. I have a perfectly good Perl 4.0 tar that I've been too busy to unpack...] Gdbm permits only one writer to a database, so perl programs need to close databases before requesting input in order to permit concurrent access to other users. As a general solution, I wrapped dbmopen in the following perl subroutine to wait with a timeout for the database to be available. Sometimes the database would be corrupted when a perl program opened a database with subroutine wait_dbmopen and closed it with dbmclose several times: $foodata{'?'}; # make sure array is defined before passing reference. . . . &wait_dbmopen(*foodata, "filename", 0444) || die "Can't open."; . . . dbmclose(foodata); . . . &wait_dbmopen(*foodata, "filename", 0444); . . . dbmclose(foodata); # This sometimes corrupts the gdm file. Issuing another dummy operation on the array before each call to wait_dbmopen seems to have fixed the problem, but I'd like to ask the perl wizzards why. I really do intend to install a later version of perl some day. Meanwhile, this is either a long fixed bug or more probably yet another interesting caveat (misunderstanding) of using the *name production... $Header: perly.c,v 3.0.1.5 90/03/27 16:20:57 lwall Locked $ Patch level: 18 ;#** Header3 ***************************************************** ;# Routine: wait_dbmopen(*array, $file, $mode, $quiet) Author: RLD ;# DESCRIPTION ;# Open a dbm database file, waiting if necessary to ;# obtain the requested permissions. (Use regular dbmclose to close ;# the database.) ;# ;# Note: perl only permits one instance of an open database at a time, ;# despite gdbm's ability to have multiple readers. ;# ;# Entry: ;# *array = an associative array to be bound to the keyfile, as in ;# dbmopen. ;# $file = filename, suitable for dbmopen. ;# $mode = open mode. ;# $quiet = a boolean telling the routine to wait quietly. This ;# suppresses "waiting" messages from appearing on STDERR. ;# Exit: ;# boolean value indicating success. ;#** EndHeader ************************************************** sub wait_dbmopen { local(*array, $file, $mode, $quiet) = @_; local($proceed) = 0; local($cnt) = 0; local($dbmname) = $file . '.pag'; if ( -f $dbmname ) { $! = 0; do { $proceed = dbmopen(array, $file, $mode); unless ($proceed) { unless ($quiet) { printf STDERR "\rWaiting %d seconds to open %s (Err: %d)\r", $cnt, $file, $!; } sleep 5; $cnt += 5; } } until ($proceed || $cnt > 3600); print STDERR "\r", (' ' x 75), "\r" if (!$quiet && $cnt > 0); } else { $proceed = dbmopen(array, $file, $mode); } $proceed; } ____________ Roger Droz Domain: roger@mav.COM () () Maverick International UUCP: uw-beaver!gtisqr!roger (_______) Mukilteo, WA ( ) | | Disclaimer: "We're all mavericks here: | | Each of us has our own opinions, (___) and the company has yet different ones!"