File: gdbm.info, Node: Locking, Next: Variables, Prev: Options, Up: Top 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. *Note 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.
