Next: , Previous: , Up: The GNU database manager   [Contents][Index]


19 File Locking

After opening a database file, GDBM locks it to ensure that the file won’t be modified by a third party while in use by the library. Exclusive lock is applied if the file is opened for writing (GDBM_NEWDB or GDBM_WRITER), and shared lock is used if it is opened for reading (GDBM_READER). If the file is already in use and locked by another process, gdbm_open will fail and return NULL. To indicate the reason of the failure, the gdbm_errno variable will be set to GDBM_CANT_BE_WRITER or GDBM_CANT_BE_READER, depending on the requested access to the database file. Normally, upon receiving such error codes, the program will retry opening the database file some time later, in the hope that the process that was working with it relinquishes the lock by that time. To facilitate this task, GDBM offers alternative function that is able, among others, to wait for the lock for a predefined amount of time.

The function gdbm_open_ext provides an extended interface for opening database files. It takes three arguments: name of the database file to open, access flags, and a pointer to struct gdbm_open_spec, a structure that provides additional details for opening or creating the database. Three fields of this structure are of particular interest: lock_wait, lock_timeout, and lock_delay.

The lock_wait field specifies lock waiting mode. Initializing it with GDBM_LOCKWAIT_RETRY instructs GDBM, upon failing to acquire the lock, to sleep for a predefined interval and retry locking. If locking fails again, this procedure is repeated, until the lock is finally acquired or total time spent exceeds a predefined timeout, whichever happens first.

The interval and timeout are specified by two fields of struct gdbm_open_spec: lock_interval and lock_timeout, correspondingly. Both fields are of struct timespec type, which is defined as follows:

struct timespec {
    time_t tv_sec;        /* seconds */
    long   tv_nsec;       /* nanoseconds */
};

The value of the nanoseconds field must be in the range 0 to 999999999.

To make sure other fields of the gdbm_open_spec structure are set to meaningful values, it must be initialized by assigning it the value of GDBM_OPEN_SPEC_INITIALIZER macro or using the gdbm_open_spec_init function.

The example below opens the file ‘t.gdbm’ for writing using the default lock waiting method, with 5 seconds timeout and 0.5 second interval between retries:

struct gdbm_open_spec spec = GDBM_OPEN_SPEC_INITIALIZER;

spec.lock_wait = GDBM_LOCKWAIT_RETRY;
spec.lock_interval.tv_nsec = 500000000;
spec.lock_timeout.tv_sec = 1;

dbf = gdbm_open_ext("t.gdbm", GDBM_WRITER, &spec);

Another lock waiting mode is GDBM_LOCKWAIT_SIGNAL. It differs from the default mode in that it uses a signal to measure the timeout, and it does not use the lock_interval field. Only lock_timeout must be initialized. This mode, however, is not suitable for use in multi-threaded programs.

See gdbm_open_ext, for a detailed discussion of gdbm_open_ext function.

Sometimes the user may want to perform their own file locking on the database file, instead of relying on the built-in mechanism. To do so, the flags passed to gdbm_open must have the GDBM_NOLOCK bit set, e.g.:

dbf = gdbm_open (filename, 0, GDBM_READER | GDBM_NOLOCK, 0, NULL);

To perform the locking, one must know the file descriptor corresponding to the opened GDBM_FILE, It is returned by the following function:

gdbm interface: int gdbm_fdesc (GDBM_FILE dbf)

Returns the file descriptor of the database dbf. This value can be used as an argument to flock, lockf or similar calls.


Next: Useful global variables, Previous: Setting options, Up: The GNU database manager   [Contents][Index]