// @(#)root/io:$Id$
// Author: Jan Fiete Grosse-Oetringhaus, 04.06.07

/*************************************************************************
 * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TLockFile                                                            //
//                                                                      //
// Lock an object using a file.                                         //
// Constructor blocks until lock is obtained. Lock is released in the   //
// destructor.                                                          //
//                                                                      //
// Use it in scope-blocks like:                                         //
// {                                                                    //
//    TLockFile lock("path.to.lock.file");                              //
//    // do something you need the lock for                             //
// } // lock is automatically released                                  //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TLockFile.h"
#include "TSystem.h"
#include "TFile.h"
#include <time.h>

ClassImp(TLockFile)

//______________________________________________________________________________
TLockFile::TLockFile(const char *path, Int_t timeLimit) : fPath(path)
{
   // Default constructor. Blocks until lock is obtained.
   // If a lock exists that is older than the given time limit,
   // the file is removed. If timeLimit <= 0, wait for ever.

   while (1) {
      if (Lock(fPath, timeLimit))
         break;

      if (gDebug > 0)
         Info("TLockFile", "did not aquire lock %s, sleeping...", fPath.Data());
      gSystem->Sleep(1000);
   }
}

//______________________________________________________________________________
TLockFile::~TLockFile()
{
   // Destructor. Releases the lock.

   if (gDebug > 0)
      Info("~TLockFile", "releasing lock %s", fPath.Data());

   gSystem->Unlink(fPath);
}

//______________________________________________________________________________
Bool_t TLockFile::Lock(const char *path, Int_t timeLimit)
{
   // Internal function that locks with the given path.

   Long_t modTime = 0;
   if (gSystem->GetPathInfo(path, 0, (Long_t*) 0, 0, &modTime) == 0) {
      if (timeLimit > 0) {
         if (gDebug > 0)
            Info("Lock", "%s modification time %ld, %ld seconds ago", path, modTime, time(0) - modTime);
         if (time(0) - modTime > timeLimit){
            gSystem->Unlink(path);
            if (gDebug > 0)
               Info("Lock", "time expired, removed %s", path);
         } else
            return kFALSE;
      } else
         return kFALSE;
   }

   TString spath = path;
   spath += "?filetype=raw";
   TFile *file = TFile::Open(spath, "CREATE");
   if (!file)
      return kFALSE;

   file->Close();
   delete file;

   // chance access to 666, so if the lock is expired, other users can remove it
   // (attention, currently only supported for local files systems)
   gSystem->Chmod(path, 0666);

   if (gDebug > 0)
      Info("Lock", "obtained lock %s", path);

   return kTRUE;
}
 TLockFile.cxx:1
 TLockFile.cxx:2
 TLockFile.cxx:3
 TLockFile.cxx:4
 TLockFile.cxx:5
 TLockFile.cxx:6
 TLockFile.cxx:7
 TLockFile.cxx:8
 TLockFile.cxx:9
 TLockFile.cxx:10
 TLockFile.cxx:11
 TLockFile.cxx:12
 TLockFile.cxx:13
 TLockFile.cxx:14
 TLockFile.cxx:15
 TLockFile.cxx:16
 TLockFile.cxx:17
 TLockFile.cxx:18
 TLockFile.cxx:19
 TLockFile.cxx:20
 TLockFile.cxx:21
 TLockFile.cxx:22
 TLockFile.cxx:23
 TLockFile.cxx:24
 TLockFile.cxx:25
 TLockFile.cxx:26
 TLockFile.cxx:27
 TLockFile.cxx:28
 TLockFile.cxx:29
 TLockFile.cxx:30
 TLockFile.cxx:31
 TLockFile.cxx:32
 TLockFile.cxx:33
 TLockFile.cxx:34
 TLockFile.cxx:35
 TLockFile.cxx:36
 TLockFile.cxx:37
 TLockFile.cxx:38
 TLockFile.cxx:39
 TLockFile.cxx:40
 TLockFile.cxx:41
 TLockFile.cxx:42
 TLockFile.cxx:43
 TLockFile.cxx:44
 TLockFile.cxx:45
 TLockFile.cxx:46
 TLockFile.cxx:47
 TLockFile.cxx:48
 TLockFile.cxx:49
 TLockFile.cxx:50
 TLockFile.cxx:51
 TLockFile.cxx:52
 TLockFile.cxx:53
 TLockFile.cxx:54
 TLockFile.cxx:55
 TLockFile.cxx:56
 TLockFile.cxx:57
 TLockFile.cxx:58
 TLockFile.cxx:59
 TLockFile.cxx:60
 TLockFile.cxx:61
 TLockFile.cxx:62
 TLockFile.cxx:63
 TLockFile.cxx:64
 TLockFile.cxx:65
 TLockFile.cxx:66
 TLockFile.cxx:67
 TLockFile.cxx:68
 TLockFile.cxx:69
 TLockFile.cxx:70
 TLockFile.cxx:71
 TLockFile.cxx:72
 TLockFile.cxx:73
 TLockFile.cxx:74
 TLockFile.cxx:75
 TLockFile.cxx:76
 TLockFile.cxx:77
 TLockFile.cxx:78
 TLockFile.cxx:79
 TLockFile.cxx:80
 TLockFile.cxx:81
 TLockFile.cxx:82
 TLockFile.cxx:83
 TLockFile.cxx:84
 TLockFile.cxx:85
 TLockFile.cxx:86
 TLockFile.cxx:87
 TLockFile.cxx:88
 TLockFile.cxx:89
 TLockFile.cxx:90
 TLockFile.cxx:91
 TLockFile.cxx:92
 TLockFile.cxx:93
 TLockFile.cxx:94
 TLockFile.cxx:95
 TLockFile.cxx:96
 TLockFile.cxx:97
 TLockFile.cxx:98
 TLockFile.cxx:99
 TLockFile.cxx:100