diff options
Diffstat (limited to 'mysql-test/lib/mtr_unique.pm')
-rw-r--r-- | mysql-test/lib/mtr_unique.pm | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/mysql-test/lib/mtr_unique.pm b/mysql-test/lib/mtr_unique.pm new file mode 100644 index 00000000..f276e6e1 --- /dev/null +++ b/mysql-test/lib/mtr_unique.pm @@ -0,0 +1,130 @@ +# -*- cperl -*- +# Copyright (c) 2006, 2008 MySQL AB, 2009 Sun Microsystems, Inc. +# Use is subject to license terms. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA + +package mtr_unique; + +use strict; +use Fcntl ':flock'; + +use base qw(Exporter); +our @EXPORT= qw(mtr_get_unique_id mtr_release_unique_id); + +use My::Platform; + +sub msg { + # print "### unique($$) - ", join(" ", @_), "\n"; +} + +my $dir; + +if(!IS_WINDOWS) +{ + $dir= "/tmp/mysql-unique-ids"; +} +else +{ + # Try to use machine-wide directory location for unique IDs, + # $ALLUSERSPROFILE . IF it is not available, fallback to $TEMP + # which is typically a per-user temporary directory + if (exists $ENV{'ALLUSERSPROFILE'} && -w $ENV{'ALLUSERSPROFILE'}) + { + $dir= $ENV{'ALLUSERSPROFILE'}."/mysql-unique-ids"; + } + else + { + $dir= $ENV{'TEMP'}."/mysql-unique-ids"; + } +} + +my $mtr_unique_fh = undef; + +END +{ + mtr_release_unique_id(); +} + +# +# Get a unique, numerical ID in a specified range. +# +# If no unique ID within the specified parameters can be +# obtained, return undef. +# +sub mtr_get_unique_id($$) { + my ($min, $max)= @_;; + + msg("get $min-$max, $$"); + + die "Can only get one unique id per process!" if defined $mtr_unique_fh; + + + # Make sure our ID directory exists + if (! -d $dir) + { + # If there is a file with the reserved + # directory name, just delete the file. + if (-e $dir) + { + unlink($dir); + } + + mkdir $dir; + chmod 0777, $dir; + + if(! -d $dir) + { + die "can't make directory $dir"; + } + } + + + my $fh; + for(my $id = $min; $id <= $max; $id++) + { + open( $fh, ">$dir/$id"); + chmod 0666, "$dir/$id"; + # Try to lock the file exclusively. If lock succeeds, we're done. + if (flock($fh, LOCK_EX|LOCK_NB)) + { + # Store file handle - we would need it to release the ID (==unlock the file) + $mtr_unique_fh = $fh; + return $id; + } + else + { + close $fh; + } + } + return undef; +} + + +# +# Release a unique ID. +# +sub mtr_release_unique_id() +{ + msg("release $$"); + if (defined $mtr_unique_fh) + { + close $mtr_unique_fh; + $mtr_unique_fh = undef; + } +} + + +1; + |