Lock file

Purpose: Locks file exclusively.

lock-file <file path> id <lock id> [ status <status> ]

lock-file attempts to create file with the full path of <file path> (deleting it if existed), and exclusively lock it. If successful, no other process can do the same unless current process ends or calls unlock-file. This statement is non-blocking, thus you can check in a sleepy loop for success (see pause-program).

<file path> should be either an existing or non-existing file with a valid file path. If existing, it will be deleted.

<lock id> (in "id" clause) is a file descriptor associated with locked file.

<status> (in "status" clause) represents the status of file locking: RIM_OKAY if successfully locked, RIM_ERR_FAILED if cannot lock (likely because another process holds a lock), RIM_ERR_INVALID if the path of the file is invalid (i.e. if it is empty), RIM_ERR_CREATE if lock file cannot be created.

Generally, this statement is used for process control. A process would use lock-file to start working on a job that only one process can do at a time; once done, by using unlock-file statement, another process will be able to issue a successful lock-file call. Typically, lock-file is issued in a sleepy loop (see pause-program), waiting for a resource to be released.

Note that file lock is not carried across children processes (i.e. if your process creates children, such as with exec-program, then such children must obtain their own lock). In addition, if a process serving a request terminates before the request could issue unlock-file, the lock will be automatically released.

You can use any file name (likely choose a name that signifies the purpose of a lock, as long as you have permissions to create it), and create any number of them. This way you can create as many "binary semaphore"-like objects as you like.
Examples
In a new directory, create a file "lock.rim" with:
cat << 'EOF' > lock.rim
%% /lock public
    // Get application home directory
    get-app directory to dir
    // Create lock file name
    set-string fname = dir + "/.lock"
    // Enter loop in which something is done, OR, program waits for others to complete their work before doing its own
    start-loop
        // Attempt to lock file
        lock-file fname id lockid status lockst
        // Check the status of locking
        if-true lockst equal RIM_OKAY
            // File successfully locked, simulate working for 20 seconds
            @WORKING
            pause-program 20000
            @DONE
            // Once done, unlock file
            unlock-file id lockid
            break-loop
        else-if lockst equal RIM_ERR_FAILED
            // Another process holds the lock, wait, try again for 1 second
            pause-program 1000
            @WAITING
            continue-loop
        else-if lockst equal RIM_ERR_OPEN or lockst equal RIM_ERR_INVALID
            // Errors
            @BAD LOCK
            exit-handler
        end-if
    end-loop
%%
EOF

Create and build a new app:
rim -k lock-app -q

Run it twice at the same time in two different terminal windows with:
rim -r --req="/lock" --exec --app="/lock" --silent-header

One window will show the following (WORKING and then after20 seconds DONE):
WORKING
DONE

The other window will show it waiting for 20 seconds to acquire the lock (held by the first process), and then work for 20 seconds just like the first one:
WAITING
WAITING
WAITING
WAITING
WAITING
WAITING
WAITING
WAITING
WAITING
WAITING
WAITING
WAITING
WAITING
WAITING
WAITING
WAITING
WAITING
WAITING
WAITING
WORKING
DONE

See also
Files
change-mode  
close-file  
copy-file  
delete-file  
file-position  
file-storage  
file-uploading  
get-upload  
lock-file  
open-file  
read-file  
read-line  
rename-file  
stat-file  
temporary-file  
uniq-file  
unlock-file  
write-file  
See all
documentation


Copyright (c) 2019-2025 Gliim LLC. All contents on this web site is "AS IS" without warranties or guarantees of any kind.