This source code is based on the fact that mkdir will create a directory atomically. If two processes try to create a dir, one and only one will succeed immediately when interrupting the current process, we need to unlock all current locks. Therefor, we need a list of locks for the current process. And we need to update this list at the same time we got the lock. liblock is used to lock and unlock resources. It should be deadlock free, and clean up locks after processes that had locks die without unlocking the files. It uses the directory $LOCK_DIR defined in /etc/sorcery/config
: Benoit PAPILLAULT
: 29/10/2003
lock_resources
Type of resource | Name of resource | Usage cast | spell name | when casting a spell file | file name | to lock a file summon | spell name | when downloading a spell network | network | ? solo | resource name | when using a resource exclusively libgrimoire | install | when a spell is in the install stagelocking solo will not cause these routines to behave any different. catching it has to be done externally (see cast for an example) this function locks the specified resource. this is a blocking function that can take an indeterminate period of time to acquire the lock. If no other processes have locked the resource, this function will return immediately
trylock_resources this function tries to lock the specified resource. On success, it immediately returns 0 (true). On failure (the lock cannot be acquired), it returns 1 (false).
excllock_resources this function works like lock_resources except that it waits for all resources of the given type to unlock before locking. This will not stop any other lock from being created, that has to be done in the code
unlock_resources this function unlocks the specified resource and returns immediately if the specified resource is : - unlocked : nothing is done - locked by this process : it's unlocked - locked by another process : it's kept locked. In all cases and for compatibility reasons with the old liblock, we return true
clean_resources this function removes all locks acquired by the current process. you can call this function at the end of your script to check for missing call to unlock_resources
global_clean_resources this function is used internaly to remove all stale locks.
Locks files for access to only this PID. Will cause attempts by other processes that want to lock the file(s) to block until this PID unlocks the file, or this PID dies. It cannot prevent bad programs from modifying the file w/o permission. Note: Files with funky chars may break things. No colons or stuff.
Unlocks a file so that another process can lock and modify it.
The name of a temporary file that should be written to instead of the real file.
A transaction locks a file and ensures that changes made to the file are all made at once. No changes are made to the file until the transaction is commited. Furthermore, a transaction can be killed before it is commited, ending the transaction and not making any changes to the files. All files are locked at once. If not all can be locked, they will be unlocked, and another try will be made.
Commits the changes made to the files as atomicaly as possible Before this func is called, the files remain unchanged.
Stops a transaction. Causes the changes to the file(s) to be ignored/undone.
Increment a counter Processes should call counter_down when done with the resource however counter_down and counter_check will clean up after misbehaving processes.
Decrement a counter
Destroy a counter
Check the value of a counter Also cleans stale items
Print out the file with non-existent pids removed Caller must hold a lock on the file
This assumes that two functions of the same name will not havethe SYNCHRONIZE command on the same line in different files.
=item SYNCHRONIZE Prevents more than one process from entering a section of code at a time
Example: #!/bin/bash echo "Script started with PID=$$ eval "$SYNCHRONIZE" && { echo "PID $$ is in the synched section of code." sleep 10 } && eval "$UNSYNCHRONIZE" echo "PID $$ done."Note: SYNCHRONIZE and UNSYNCHRONIZE must be in the same local scope. Nested SYNCHs are not allowed in the same local scopes. Local scope usualy being a function.
=item UNSYNCHRONIZE Terminates a section of SYNCHRONIZED code