[2/3] testbot/lib: Add a utility function to atomically create a new hardlink.

Francois Gouget fgouget at codeweavers.com
Mon Jun 16 09:11:12 CDT 2014


It ensures there are no race conditions with other processes and simplifies the calling code.
---
 testbot/lib/WineTestBot/Patches.pm | 11 ++++-------
 testbot/lib/WineTestBot/Utils.pm   | 16 +++++++++++++++-
 2 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/testbot/lib/WineTestBot/Patches.pm b/testbot/lib/WineTestBot/Patches.pm
index bb7ea3f..98cc6c2 100644
--- a/testbot/lib/WineTestBot/Patches.pm
+++ b/testbot/lib/WineTestBot/Patches.pm
@@ -33,6 +33,8 @@ linked to this patch through a WineTestBot::PendingPatch object.
 =cut
 
 use Encode qw/decode/;
+use File::Basename;
+
 use WineTestBot::Config;
 use WineTestBot::PendingPatchSets;
 use WineTestBot::Jobs;
@@ -206,13 +208,8 @@ sub Submit
     my $Steps = $NewJob->Steps;
     my $NewStep = $Steps->Add();
     # Create a link to the patch file in the staging dir
-    my $FileNameRandomPart = GenerateRandomString(32);
-    while (-e ("$DataDir/staging/${FileNameRandomPart}_patch.diff"))
-    {
-      $FileNameRandomPart = GenerateRandomString(32);
-    }
-    link $PatchFileName, "$DataDir/staging/${FileNameRandomPart}_patch.diff";
-    $NewStep->FileName($FileNameRandomPart . "_patch.diff");
+    my $StagingFileName = CreateNewLink($PatchFileName, "$DataDir/staging", "_patch.diff");
+    $NewStep->FileName(basename($StagingFileName));
     my @Keys = keys %{$Targets{$BaseName}};
     $NewStep->FileType($Targets{$BaseName}{$Keys[0]});
     $NewStep->InStaging(1);
diff --git a/testbot/lib/WineTestBot/Utils.pm b/testbot/lib/WineTestBot/Utils.pm
index f05c7dc..1cea5d7 100644
--- a/testbot/lib/WineTestBot/Utils.pm
+++ b/testbot/lib/WineTestBot/Utils.pm
@@ -33,7 +33,7 @@ use vars qw (@ISA @EXPORT);
 require Exporter;
 @ISA = qw(Exporter);
 @EXPORT = qw(&MakeSecureURL &SecureConnection &GenerateRandomString
-             &OpenNewFile &CreateNewFile &BuildEMailRecipient);
+             &OpenNewFile &CreateNewFile &CreateNewLink &BuildEMailRecipient);
 
 sub MakeSecureURL($)
 {
@@ -91,6 +91,20 @@ sub CreateNewFile($$)
   return $FileName;
 }
 
+sub CreateNewLink($$$)
+{
+  my ($OldFileName, $Dir, $Suffix) = @_;
+
+  while (1)
+  {
+    my $Link = "$Dir/" . GenerateRandomString(32) . $Suffix;
+    return $Link if (link $OldFileName, $Link);
+
+    # This is not an error that will be fixed by trying a different path
+    return undef if (!$!{EEXIST});
+  }
+}
+
 sub DateTimeToString($)
 {
   my ($Time) = @_;
-- 
2.0.0




More information about the wine-patches mailing list