[Gambas-user] How to lock a file

Rolf-Werner Eilert eilert-sprachen at ...221...
Wed Oct 8 11:45:31 CEST 2008


Benoit Minisini schrieb:
> On mardi 07 octobre 2008, Rolf-Werner Eilert wrote:
>> Benoit Minisini schrieb:
>>> On mardi 07 octobre 2008, nando wrote:
>>>> There is a problem with your method.
>>>> Between the execution of the KILL and the CREATION of the file,
>>>> multitasking happens and another task could create the file just before
>>>> the original thread executed the CREATE.
>>>>
>>>> In different words, if the first thread lost the CPU just after the KILL
>>>> command due to multitasking and a second thread began the WHILE
>>>> condition, the WHILE would not execute because the WHILE condition fails
>>>> and then the file is CREATED with the user of the second thread.
>>>> Then, multitasking happens and the second thread loses the CPU and the
>>>> first thread continues and it will then create the file destroying the
>>>> second threads information.  Anything could happen in a multitasking
>>>> environment.
>>>>
>>>> I use directories because folder creation is a one-step process there
>>>> isn't time between the two steps for
>>>> another task to steal the lock in betweem code statements.
>>>> An example is something like...
>>>>
>>>> 'create lock, this can be in a SUB with tje folder name passed in
>>>>
>>>> counter=100     '100 loops of 0.1 sec = 10 seconds max to try lock
>>>> flag = FALSE
>>>> WHILE flag = FALSE
>>>>   TRY MKDIR "lock-folder-name"
>>>>   IF ERROR THEN  'it failed
>>>>     flag=TRUE
>>>>     error.clear
>>>>     WAIT 0.1
>>>>     dec counter
>>>>     if counter<=0 then
>>>>       'you could say the the lock took too long
>>>>       'you could allow a user choice to retry or blindly continue.
>>>>       break   'we will assume something is locked too long
>>>>     endif
>>>>   else
>>>>     flag=FALSE
>>>>   endif
>>>> wend
>>>>
>>>>
>>>> 'unlock, this can be a SUB too
>>>> TRY RMDKR "lock-folder-name"
>>>> error.clear
>>>>
>>>> You don't need to know who has the lock because only a successful lock
>>>> leads to code writing some important information for the thread that
>>>> successfully locked.  The unlock must follow very shortly thereafter to
>>>> release the lock and cannot hog the lock.
>>>>
>>>> -Fernando
>>> Or better method: use the LOCK / UNLOCK instruction!
>> Yes Benoit, we know, but this is hobby :-) just having fun with an own
>> algorithm...
>>
>>
>> But I've got a question about LOCK. I didn't know it existed. A long
>> time ago when I started with Linux, I learned that Linux doesn't have a
>> file locking mechanism. Isn't that true anymore? Never heard or read
>> about it in all these years.
>>
>> After all, a lot of programs still use lock files, and for instance
>> there is a discussion about Firefox 3 not running correctly on terminal
>> servers because it's got a new file locking method which blocks more
>> than 1 users.
>>
>> Having a first glance at the description of LOCK, there is one thing
>> which leaves at least a small pain in the neck: You have to open the
>> stream before being able to try a lock. That leaves the impression that
>> without checking the lock, you can read/write the file anyway. Two
>> questions:
>>
>> Is this LOCK just a flag? (Which I can obey or not just like I feel) Or
>> does it really prevent any other access (or at least writing into the
>> file)?
>>
>> And what happens if my program "forgets" Unlocking it? Will the file
>> stay locked (file system wide - until reboot) or will the Lock end
>> automagically when I close the file or when the process ends that opened
>> the stream?
>>
>> (Maybe it would be nice to insert such information into the help, too)
>>
>> Regards
>>
>> Rolf
>>

Thank you Benoit for your answer! Now I tried around with it a bit and 
tested the example from the Wiki, and there are some questions left:

> 
> The documentation you read is false and out of date. Look at the updated 
> documentation in the wiki.
> 
> I cannot say more than what I already wrote there:
> 
> LOCK uses a file to create a system-wide global lock. Without using a file, it 
> couldn't be system-wide.

Alright, but it doesn't delete the lock-file with UNLOCK, and the 
lock-file has standard rights rw-r--r-- (644), so no other user than the 
one who has created it should be able to delete it. Up to now, I just 
tested it on my own account with a file from my own, but I would be 
surprised if this mechanism made an exception from such basic rules here.

DIM hLock AS Stream
' Try to acquire the lock
TRY hLock = LOCK "~/my-lock"
IF ERROR THEN
   PRINT "Locked is already acquired. Try again later."
   RETURN
ENDIF
' File is locked, you can do the job now!
...
' Do not forget to release the lock
UNLOCK hLock

The most important question here is: What file does this lock-file lock 
(or: what file does it refer to)? But then:

> 
> It actually uses the lockf() POSIX file lock routine to lock the file so that 
> only one process at a time can acquire the lock.

Browsing through the descriptions of lockf() and fcntl() in the internet 
I found there are two different ways of implementation: mandatory and 
advisory. From my first tests here I assume that you chose advisory, is 
that correct? This would mean, your implementation doesn't refer to a 
specific file but can be just set or unset as it is used from time to 
time by the specific Gambas application, but it doesn't have any effect 
on other apps accessing the locked file. Am I right here?

> 
> The contents of the underlying file is not important. But do not write in it, 
> as acquiring the lock automatically voids the file!
> 
> LOCK returns a Stream object that you use to UNLOCK the file. 
> 
> And halting the process automatically releases the lock - Important feature!

But the lock-file doesn't disappear nor are its rights changed - so how 
is it unlocked?

> 
> I hope I have shown that LOCK is useful :-)

Oh yes, I never doubted that, but I have to know how it works to be able 
to use it properly :-)

Regards

Rolf




More information about the User mailing list