File locking using threads

Discussion in 'Perl Misc' started by Prince Al, Oct 23, 2009.

  1. Prince Al

    Prince Al Guest

    Hi,

    I am attempting to write a some code that spawns various threads. Each
    thread will need to access a common file and to ensure that this file
    is only written to by one thread at a time, it needs to be locked.
    However, I am having trouble even creating a test script to try out
    the logic, which is below. What happens is that both threads are able
    to acquire the lock, even though the first thread should have it and
    release it before the second thread is able to lock the file. Any
    assistance will be very gratefully received!

    Cheers

    Tim

    #!usr/bin/perl

    use strict;
    use threads;

    my $thr_1 = threads->new(\&flock_test,5, 20, "Thread 1");
    my $thr_2 = threads->new(\&flock_test,10, 5, "Thread 2");

    grep {$_->join;} ($thr_1,$thr_2);
    # Just In Case!
    while ( my(@list)=threads->list()) {
    print "$#list\n";
    grep { $_->join } @list;
    };
    exit;

    sub flock_test {
    open(my $fh, ">", "/tmp/flock_test.dat");
    my $sleep_1 = $_[0];
    my $sleep_2 = $_[1];
    my $thread_name = $_[2];

    sleep $sleep_1;

    flock($fh,2) || die "Could not acquire the lock\n";
    print "$thread_name: acquired lock!\n";
    sleep $sleep_2;
    close $fh;
    print "$thread_name: released lock!\n";
    }
    Prince Al, Oct 23, 2009
    #1
    1. Advertising

  2. Prince Al <> wrote:
    > I am attempting to write a some code that spawns various threads. Each
    > thread will need to access a common file and to ensure that this file
    > is only written to by one thread at a time, it needs to be locked.
    > However, I am having trouble even creating a test script to try out
    > the logic, which is below. What happens is that both threads are able
    > to acquire the lock, even though the first thread should have it and
    > release it before the second thread is able to lock the file. Any
    > assistance will be very gratefully received!


    > #!usr/bin/perl


    > use strict;
    > use threads;


    > my $thr_1 = threads->new(\&flock_test,5, 20, "Thread 1");
    > my $thr_2 = threads->new(\&flock_test,10, 5, "Thread 2");


    > grep {$_->join;} ($thr_1,$thr_2);
    > # Just In Case!
    > while ( my(@list)=threads->list()) {
    > print "$#list\n";
    > grep { $_->join } @list;
    > };
    > exit;


    > sub flock_test {
    > open(my $fh, ">", "/tmp/flock_test.dat");
    > my $sleep_1 = $_[0];
    > my $sleep_2 = $_[1];
    > my $thread_name = $_[2];


    > sleep $sleep_1;


    > flock($fh,2) || die "Could not acquire the lock\n";


    Works ok on my machine. My guess is that on yours LOCK_EX (that's
    what you need here) isn't 2. Better use

    use Fcntl ':flock';

    to import the constants used for flock() and then write

    flock($fh,LOCK_EX) || die "Could not acquire the lock\n";

    Regards, Jens
    --
    \ Jens Thoms Toerring ___
    \__________________________ http://toerring.de
    Jens Thoms Toerring, Oct 23, 2009
    #2
    1. Advertising

  3. Prince Al

    Guest

    Prince Al <> wrote in message-id: <>

    >
    > Hi,
    >
    > I am attempting to write a some code that spawns various threads. Each
    > thread will need to access a common file and to ensure that this file
    > is only written to by one thread at a time, it needs to be locked.
    > However, I am having trouble even creating a test script to try out
    > the logic, which is below. What happens is that both threads are able
    > to acquire the lock, even though the first thread should have it and
    > release it before the second thread is able to lock the file. Any
    > assistance will be very gratefully received!
    >
    > Cheers
    >
    > Tim
    >
    > #!usr/bin/perl
    >
    > use strict;
    > use threads;
    >
    > my $thr_1 = threads->new(\&flock_test,5, 20, "Thread 1");
    > my $thr_2 = threads->new(\&flock_test,10, 5, "Thread 2");
    >
    > grep {$_->join;} ($thr_1,$thr_2);
    > # Just In Case!
    > while ( my(@list)=threads->list()) {
    > print "$#list\n";
    > grep { $_->join } @list;
    > };
    > exit;
    >
    > sub flock_test {
    > open(my $fh, ">", "/tmp/flock_test.dat");
    > my $sleep_1 = $_[0];
    > my $sleep_2 = $_[1];
    > my $thread_name = $_[2];
    >
    > sleep $sleep_1;
    >
    > flock($fh,2) || die "Could not acquire the lock\n";
    > print "$thread_name: acquired lock!\n";
    > sleep $sleep_2;
    > close $fh;
    > print "$thread_name: released lock!\n";
    > }


    You might like threads::shared for inter thread communication.

    You set up your shared variables then launch your threads.
    Have the threads monitor and update the shared variables
    to determine the status of the file or other things.

    All threads will have access to the entire %shash.

    foreach my $tID (1..2) {
    warn 'Launching thread: [' . $tID . "]\n";
    foreach my $l qw (fileIsLocked, go, stop, quit,) {
    share($shash{1}{$l});
    $shash{$tID}{$l} = 0;
    }
    $threads{$tID} = threads->new(\&worker, 1);
    warn 'Thread: [' . $tID . "] is active\n";
    }

    sub worker #------------------------------------------------------------
    {
    #called from main
    my $TID = $_[0] || 0;

    while(1) {
    if ($shash{$TID}{quit} == 1) {
    last;
    }
    elsif ($shash{$TID}{fileIsLocked} == 1) {

    }
    #etc...
    sleep (1);
    }
    return (1);
    }

    Hth,
    J
    , Oct 24, 2009
    #3
  4. Prince Al

    Guest

    wrote in message-id: <w_EEm.8817$>

    >
    >
    > Prince Al <> wrote in message-id: <>
    >
    > >
    > > Hi,
    > >
    > > I am attempting to write a some code that spawns various threads. Each
    > > thread will need to access a common file and to ensure that this file
    > > is only written to by one thread at a time, it needs to be locked.
    > > However, I am having trouble even creating a test script to try out
    > > the logic, which is below. What happens is that both threads are able
    > > to acquire the lock, even though the first thread should have it and
    > > release it before the second thread is able to lock the file. Any
    > > assistance will be very gratefully received!
    > >
    > > Cheers
    > >
    > > Tim
    > >
    > > #!usr/bin/perl
    > >
    > > use strict;
    > > use threads;
    > >
    > > my $thr_1 = threads->new(\&flock_test,5, 20, "Thread 1");
    > > my $thr_2 = threads->new(\&flock_test,10, 5, "Thread 2");
    > >
    > > grep {$_->join;} ($thr_1,$thr_2);
    > > # Just In Case!
    > > while ( my(@list)=threads->list()) {
    > > print "$#list\n";
    > > grep { $_->join } @list;
    > > };
    > > exit;
    > >
    > > sub flock_test {
    > > open(my $fh, ">", "/tmp/flock_test.dat");
    > > my $sleep_1 = $_[0];
    > > my $sleep_2 = $_[1];
    > > my $thread_name = $_[2];
    > >
    > > sleep $sleep_1;
    > >
    > > flock($fh,2) || die "Could not acquire the lock\n";
    > > print "$thread_name: acquired lock!\n";
    > > sleep $sleep_2;
    > > close $fh;
    > > print "$thread_name: released lock!\n";
    > > }

    >
    > You might like threads::shared for inter thread communication.
    >
    > You set up your shared variables then launch your threads.
    > Have the threads monitor and update the shared variables
    > to determine the status of the file or other things.
    >
    > All threads will have access to the entire %shash.
    >
    > foreach my $tID (1..2) {
    > warn 'Launching thread: [' . $tID . "]\n";
    > foreach my $l qw (fileIsLocked, go, stop, quit,) {
    > share($shash{1}{$l});
    > $shash{$tID}{$l} = 0;
    > }
    > $threads{$tID} = threads->new(\&worker, 1);
    > warn 'Thread: [' . $tID . "] is active\n";
    > }
    >
    > sub worker #------------------------------------------------------------
    > {
    > #called from main
    > my $TID = $_[0] || 0;
    >
    > while(1) {
    > if ($shash{$TID}{quit} == 1) {
    > last;
    > }
    > elsif ($shash{$TID}{fileIsLocked} == 1) {
    >
    > }
    > #etc...
    > sleep (1);
    > }
    > return (1);
    > }
    >
    > Hth,
    > J


    Hrmph, typo, just half way through my am coffee and still a bit tired.
    For this to work right you would have to fix above thread launching code
    replacing the 1's within the foreach my $tID (1..2) {} block with $tID
    , Oct 24, 2009
    #4
  5. Prince Al

    Guest

    In article <>,
    Prince Al says...

    >sub flock_test {
    > open(my $fh, ">", "/tmp/flock_test.dat");
    > my $sleep_1 = $_[0];
    > my $sleep_2 = $_[1];
    > my $thread_name = $_[2];
    >
    > sleep $sleep_1;



    why do you even have to lock the file via flock. Threads can lock
    variables and that is faster and safer. Just create a shared variable
    which you can use as a semaphore between threads. Unless that variable
    is locked first, no thread can write to the file. Release the lock
    once written.

    I have done this in my of my scripts and it works great.
    , Oct 25, 2009
    #5
  6. Prince Al

    Prince Al Guest

    Hi,

    Many thanks for the replies so far - very much appreciated! I tried
    your various suggestions on my Linux machine and they worked like a
    charm, however, moving this code onto the work servers did not prove
    quite so fruitful... This are running Solaris (HP-UX B.11.11 U) and
    given the way most things are at my company, configured incorrectly!

    To answer a question posed above, the reason I want to lock a file
    instead of using shared variables is because there will potentially be
    many instances of the final script running and I want a way to manage
    machine resources. I am writing a data load scheduler by the way...
    So, when an instance of the script wants to grab a resource, it locks
    the file and subtracts 1 (for example) from the number contained in
    the file and when it finishes, it locks the file and adds 1 to the
    contents of the file. In a nutshell.

    Hopefully that is clear enough! Again, thanks in advance for any
    assitance :)

    Cheers

    Tim
    Prince Al, Oct 25, 2009
    #6
  7. Prince Al <> wrote:
    > Many thanks for the replies so far - very much appreciated! I tried
    > your various suggestions on my Linux machine and they worked like a
    > charm, however, moving this code onto the work servers did not prove
    > quite so fruitful... This are running Solaris (HP-UX B.11.11 U) and
    > given the way most things are at my company, configured incorrectly!


    Out of curiosity, How was it mis-configured not to let you get a
    lock on a file? The only thing I can think of at the moment is
    that the file to be locked is on an NFS mounted disk and the
    normal (non-Perl but POSIX) flock() function often does not
    work with NFS - and usually Perl's flock() function is based on
    POSIX's flock() function. If that should be the case you might
    be better off using the POSIX fcntl() function, with one way to
    do that would be to use a module I uploaded to CPAN, called
    File::FcntlLock (current version is 0.12).

    Regards, Jens
    --
    \ Jens Thoms Toerring ___
    \__________________________ http://toerring.de
    Jens Thoms Toerring, Oct 25, 2009
    #7
  8. Prince Al

    Prince Al Guest

    On Oct 25, 6:55 pm, (Jens Thoms Toerring) wrote:
    > Out of curiosity, How was it mis-configured not to let you get a
    > lock on afile? The only thing I can think of at the moment is
    > that thefileto be locked is on an NFS mounted disk ...


    Hi Jens,

    Sorry, after re-reading my post, I realised that bit might have been
    unclear! I have no idea if there is a mis-configuration - I was just
    musing out loud and was wondering if there could be such a scenario to
    prevent this from working. Instead of placing the file to be locked
    in /tmp, I have placed it in my home directory to test the scenario
    about different mounts out, with the same results...

    My current script is pasted below, oh, and the version of Perl we have
    on the server is 5.8.3, if that is any use.

    Thanks again for any help!

    Cheers

    Tim

    #!usr/bin/perl

    use strict;
    use threads;
    use Fcntl qw/:flock/;

    my @args_1 = (5, 20, "Thread 1");
    my @args_2 = (10, 5, "Thread 2");


    my $thr_1 = threads->new(\&flock_test,5, 20, "Thread 1");
    my $thr_2 = threads->new(\&flock_test,10, 5, "Thread 2");

    $_->join for $thr_1,$thr_2;

    sub flock_test {
    open(my $fh, ">", "/home/thill/flock_test.dat");
    my $sleep_1 = $_[0];
    my $sleep_2 = $_[1];
    my $thread_name = $_[2];

    sleep $sleep_1;

    #flock($fh,LOCK_EX) || die "Could not acquire the lock\n";

    print "$thread_name: acquired lock!\n";
    sleep $sleep_2;
    close $fh;
    print "$thread_name: released lock!\n";
    }
    Prince Al, Oct 25, 2009
    #8
  9. Prince Al <> wrote:
    > On Oct 25, 6:55 pm, (Jens Thoms Toerring) wrote:
    > > Out of curiosity, How was it mis-configured not to let you get a
    > > lock on afile? The only thing I can think of at the moment is
    > > that thefileto be locked is on an NFS mounted disk ...


    > Sorry, after re-reading my post, I realised that bit might have been
    > unclear! I have no idea if there is a mis-configuration - I was just
    > musing out loud and was wondering if there could be such a scenario to
    > prevent this from working. Instead of placing the file to be locked
    > in /tmp, I have placed it in my home directory to test the scenario
    > about different mounts out, with the same results...


    > My current script is pasted below, oh, and the version of Perl we have
    > on the server is 5.8.3, if that is any use.


    > #!usr/bin/perl


    That's rather likely meant to be

    #!/usr/bin/perl

    > use strict;
    > use threads;
    > use Fcntl qw/:flock/;


    > my @args_1 = (5, 20, "Thread 1");
    > my @args_2 = (10, 5, "Thread 2");


    > my $thr_1 = threads->new(\&flock_test,5, 20, "Thread 1");
    > my $thr_2 = threads->new(\&flock_test,10, 5, "Thread 2");


    > $_->join for $thr_1,$thr_2;


    > sub flock_test {
    > open(my $fh, ">", "/home/thill/flock_test.dat");
    > my $sleep_1 = $_[0];
    > my $sleep_2 = $_[1];
    > my $thread_name = $_[2];


    > sleep $sleep_1;


    > #flock($fh,LOCK_EX) || die "Could not acquire the lock\n";


    > print "$thread_name: acquired lock!\n";
    > sleep $sleep_2;
    > close $fh;
    > print "$thread_name: released lock!\n";
    > }


    Mmm, since you commented out the line where flock() is called
    I would expect that you won't get a lock but also no error
    message that locking failed;-)

    Another thing I notice, which might result in trouble, is that
    both threads open the file in write mode ('>'). That leads to
    both threads emptying the file (i.e. possibly modifying it)
    before asking for the lock which, as far as I have understood
    your intentions, isn't what you're planning to do. I guess it
    would make more sense to use '+<' (or '>>') instead of '>' when
    opening the file to avoid that.

    And, BTW, using 'use warnings;' is usually rather useful;-)

    Regards, Jens
    --
    \ Jens Thoms Toerring ___
    \__________________________ http://toerring.de
    Jens Thoms Toerring, Oct 25, 2009
    #9
  10. Prince Al

    Prince Al Guest

    On Oct 25, 8:46 pm, (Jens Thoms Toerring) wrote:
    > #!/usr/bin/perl


    Thanks - corrected.

    > Mmm, since you commented out the line where flock() is called
    > I would expect that you won't get a lock but also no error
    > message that locking failed;-)


    Dang - not making a good first impression here, am I?! I did actually
    notice this just before I replied and tested the code without the
    crucial line commented out, but same result. I obviously forgot to re-
    copy the updated code...

    > Another thing I notice, which might result in trouble, is that
    > both threads open the file in write mode ('>'). That leads to
    > both threads emptying the file (i.e. possibly modifying it)
    > before asking for the lock which, as far as I have understood
    > your intentions, isn't what you're planning to do. I guess it
    > would make more sense to use '+<' (or '>>') instead of '>' when
    > opening the file to avoid that.


    Fair point, thank you.

    > And, BTW, using 'use warnings;' is usually rather useful;-)


    Done
    Prince Al, Oct 25, 2009
    #10
  11. Prince Al <> wrote:
    > > Mmm, since you commented out the line where flock() is called
    > > I would expect that you won't get a lock but also no error
    > > message that locking failed;-)


    > Dang - not making a good first impression here, am I?! I did actually
    > notice this just before I replied and tested the code without the
    > crucial line commented out, but same result. I obviously forgot to re-
    > copy the updated code...


    S**t happens;-) But what is actually the "same result"? And
    are you sure that your home directory isn't on a NFS mounted
    partition or that flock() on the system you're testing this
    on works with NFS partitons? I guess the man page for flock(2)
    should tell you (or, if it's silent abut that topic it might
    be better to assume that that it doesn't work wit NFS).

    Regards, Jens
    --
    \ Jens Thoms Toerring ___
    \__________________________ http://toerring.de
    Jens Thoms Toerring, Oct 25, 2009
    #11
  12. Prince Al

    Prince Al Guest

    On Oct 25, 9:21 pm, (Jens Thoms Toerring) wrote:
    > S**t happens;-) But what is actually the "same result"?


    When I run the script, I get:

    Thread 1: acquired lock!
    Thread 2: acquired lock!
    Thread 2: released lock!
    Thread 1: released lock!

    Which is obviously wrong as Thread 1 should complete before Thread 2
    can obtain the lock...

    > And
    > are you sure that your home directory isn't on a NFS mounted
    > partition or that flock() on the system you're testing this
    > on works with NFS partitons?


    No, I am not sure. However, there is no man page for flock. I have
    lockf however - is this the same/similar? From the man page, it seems
    to do a similar job, although I'm not sure it helps me any...
    Prince Al, Oct 25, 2009
    #12
  13. Prince Al <> wrote:
    > On Oct 25, 9:21 pm, (Jens Thoms Toerring) wrote:
    > > S**t happens;-) But what is actually the "same result"?


    > When I run the script, I get:


    > Thread 1: acquired lock!
    > Thread 2: acquired lock!
    > Thread 2: released lock!
    > Thread 1: released lock!


    > Which is obviously wrong as Thread 1 should complete before Thread 2
    > can obtain the lock...


    > > And
    > > are you sure that your home directory isn't on a NFS mounted
    > > partition or that flock() on the system you're testing this
    > > on works with NFS partitons?


    > No, I am not sure. However, there is no man page for flock. I have
    > lockf however - is this the same/similar? From the man page, it seems
    > to do a similar job, although I'm not sure it helps me any...


    I think Ben's idea to start by figuring out what Perl really uses
    when flock() is called is a very sensible proposal (and, of course,
    he's correct when pointing out that flock() isn't a POSIX function
    at all but a BSDism). Once you have figured that out (and it turns
    to be flock() anyway) then you might ask your system administrator
    NFS is use at all and what partitions it's used for. Perhaps that's
    just a red hering, but I am not aware at the moment of any other
    reasons for failure of locking the file (unless there are some
    special issues with your system and locks and threads...).

    Of course, ait could also be the case that Perl's flock() uses
    lockf() internally, but I haven't seen anything concerning lockf()
    that would easily explain the problems you're running into. But
    perhaps the man page for lockf() on your system has some hints
    but I can't check since I have no access to it.

    Regards, Jens
    --
    \ Jens Thoms Toerring ___
    \__________________________ http://toerring.de
    Jens Thoms Toerring, Oct 26, 2009
    #13
  14. Ben Morrow wrote:
    >
    > I don't know what the usual behaviour of flock is under NFS, but I would
    > expect to get EINVAL or some such rather than silently appearing to
    > succeed without actually locking anything. (I believe my system
    > (FreeBSD) returns EOPNOTSUPP.)


    The behavior that I usually see with flock over NFS is that it works as
    expected within one machine, just as if the file were a local one. But
    processes running on different machines will silently be granted
    conflicting locks on the same file. If the file were exposed to the
    same machine via different NFS mounts, then presumably you could get
    conflicting locks by using different NFS paths to open.

    But obviously there are more permutations than just the ones I have
    witnessed.

    Xho
    Xho Jingleheimerschmidt, Oct 27, 2009
    #14
  15. Prince Al

    Prince Al Guest

    Hi all,

    First, many thanks for the taking the time to help me out - very much
    appreciated :) Answers to the various queries posted above are...

    OS is HP-UX B.11.11 U

    There are NFS mounts in use on the server, but none where I have been
    trying to lock a file

    I have found 5 files relating to sys/syscall.h and none of them
    contain any reference to 'SYS_flock':
    /usr/conf/pa/sys/syscall.h
    /usr/conf/sys/syscall.h
    /usr/include/sys/syscall.h
    /usr/include/pa/sys/syscall.h
    /usr/include/syscall.h

    lockf man page snippets:
    NAME
    lockf - provide semaphores and record locking on files

    SYNOPSIS
    #include <unistd.h>

    int lockf(int fildes, int function, off_t size);

    DESCRIPTION
    The lockf() function allows regions of a file to be used as
    semaphores
    (advisory locks) or restricts access to only the locking process
    (enforcement-mode record locks). Other processes that attempt
    to
    access the locked resource either return an error or sleep until
    the
    resource becomes unlocked. All locks for a process are released
    upon
    the first close of the file, even if the process still has the
    file
    opened, and all locks held by a process are released when the
    process
    terminates.

    fildes is an open file descriptor. The file descriptor must
    have been
    opened with write-only permission (O_WRONLY) or read-write
    permission
    (O_RDWR) in order to establish a lock with this function call
    (see
    open(2)).

    If the calling process is a member of a group that has the
    PRIV_LOCKRDONLY privilege (see getprivgrp(2)), it can also use
    lockf()
    to lock files opened with read-only permission (O_RDONLY).

    function is a control value that specifies the action to be
    taken.
    Permissible values for function are defined in <unistd.h> as
    follows:

    #define F_ULOCK 0 /* unlock a region */
    #define F_LOCK 1 /* lock a region */
    #define F_TLOCK 2 /* test and lock a region */
    #define F_TEST 3 /* test region for lock */

    All other values of function are reserved for future extensions
    and
    result in an error return if not implemented.

    F_TEST is used to detect whether a lock by another process is
    present
    on the specified region. lockf() returns zero if the region is
    accessible and -1 if it is not; in which case errno is set to
    EACCES.
    F_LOCK and F_TLOCK both lock a region of a file if the region is
    available. F_ULOCK removes locks from a region of the file.

    size is the number of contiguous bytes to be locked or
    unlocked. The
    resource to be locked starts at the current offset in the file,
    and
    extends forward for a positive size, and backward for a negative
    size
    (the preceding bytes up to but not including the current
    offset). If
    size is zero, the region from the current offset through the end
    of
    the largest possible file is locked (that is, from the current
    offset
    through the present or any future end-of-file). An area need
    not be

    Hewlett-Packard Company - 1 - HP-UX Release 11i:
    November 2000

    lockf(2)
    lockf(2)

    allocated to the file in order to be locked, because such locks
    can
    exist past the end of the file.

    Regions locked with F_LOCK or F_TLOCK can, in whole or in part,
    contain or be contained by a previously locked region for the
    same
    process. When this occurs or if adjacent regions occur, the
    regions
    are combined into a single region. If the request requires that
    a new
    element be added to the table of active locks but the table is
    already
    full, an error is returned, and the new region is not locked.

    F_LOCK and F_TLOCK requests differ only by the action taken if
    the
    resource is not available: F_LOCK causes the calling process to
    sleep
    until the resource is available, whereas F_TLOCK returns an
    EACCES
    error if the region is already locked by another process.

    F_ULOCK requests can, in whole or part, release one or more
    locked
    regions controlled by the process. When regions are not fully
    released, the remaining regions are still locked by the process.
    Releasing the center section of a locked region requires an
    additional
    element in the table of active locks. If this table is full, an
    EDEADLK error is returned, and the requested region is not
    released.

    Regular files with the file mode of S_ENFMT, not having the
    group
    execute bit set, will have an enforcement policy enabled. With
    enforcement enabled, reads and writes that would access a locked
    region sleep until the entire region is available if O_NDELAY is
    clear, but return -1 with errno set if O_NDELAY is set. File
    access
    by other system functions, such as exec(), are not subject to
    the
    enforcement policy. Locks on directories, pipes, and special
    files
    are advisory only; no enforcement policy is used.

    A potential for deadlock occurs if a process controlling a
    locked
    resource is put to sleep by accessing the locked resource of
    another
    process. Thus, calls to fcntl(), lockf(), read(), or write()
    (see
    fcntl(2), lockf(2), read(2), and write(2)) scan for a deadlock
    prior
    to sleeping on a locked resource. Deadlock is not checked for
    the
    wait() and pause() system calls (see wait(2) and pause(2)), so
    potential for deadlock is not eliminated. A creat() call or an
    open()
    call with the O_CREATE and O_TRUNC flags set on a regular file
    returns
    error EAGAIN if another process has locked part of the file and
    the
    file is currently in enforcement mode.

    NETWORKING FEATURES
    NFS
    The advisory record-locking capabilities of lockf() are
    implemented
    throughout the network by the ``network lock daemon'' (see lockd
    (1M)).
    If the file server crashes and is rebooted, the lock daemon
    attempts
    to recover all locks associated with the crashed server. If a
    lock
    cannot be reclaimed, the process that held the lock is issued a
    SIGLOST signal.

    Hewlett-Packard Company - 2 - HP-UX Release 11i:
    November 2000

    lockf(2)
    lockf(2)

    Only advisory record locking is implemented for NFS files.

    RETURN VALUE
    Upon successful completion, a value of 0 is returned.
    Otherwise, a
    value of -1 is returned and errno is set to indicate the error.

    ERRORS
    lockf() fails if any of the following occur:

    [EACCES] function is F_TLOCK or F_TEST and the region
    is
    already locked by another process.

    [EBADF] fildes is not a valid, open file descriptor.

    [EDEADLK] A deadlock would occur or the number of
    entries in
    the system lock table would exceed a system-
    dependent maximum. HP-UX guarantees this
    value to
    be at least 50.

    [EINTR] A signal was caught during the lockf()
    system
    call.

    [EINVAL] Either function is not one of the functions
    specified above, or size plus current offset
    produces a negative offset into the file.

    [EINVAL] size plus current offset cannot be
    represented
    correctly by an object of size off_t.

    [ENOLCK] Either function is F_TLOCK or F_LOCK and the
    file
    is an NFS file with access bits set for
    enforcement mode, or the file is an NFS file
    and a
    system error occurred on the remote node.

    WARNINGS
    Deadlock conditions may arise when either the wait() or pause()
    system
    calls are used in conjunction with enforced locking (see wait(2)
    and
    pause(2) for details).

    When a file descriptor is closed, all locks on the file from the
    calling process are deleted, even if other file descriptors for
    that
    file (obtained through dup() or open(), for example) still
    exist.

    Unexpected results may occur in processes that use buffers in
    the user
    address space. The process may later read or write data which
    is or
    was locked. The standard I/O package, stdio(3S), is the most
    common
    source of unexpected buffering.

    In a hostile environment, locking can be misused by holding key
    public
    resources locked. This is particularly true with public read
    files
    that have enforcement enabled.

    Hewlett-Packard Company - 3 - HP-UX Release 11i:
    November 2000

    lockf(2)
    lockf(2)

    It is not recommended that the PRIV_LOCKRDONLY capability be
    used
    because it is provided for backward compatibility only. This
    feature
    may be modified or dropped from future HP-UX releases.

    Locks default to advisory mode unless the setgid bit of the file
    permissions is set.

    Application Usage
    Because in the future the variable errno will be set to EAGAIN
    rather
    than EACCES when a section of a file is already locked by
    another
    process, portable application programs should expect and test
    for
    either value. For example:

    if (lockf(fd, F_TLOCK, siz) == -1)
    if ((errno == EAGAIN) || (errno == EACCES))
    /*
    * section locked by another process
    * check for either EAGAIN or EACCES
    * due to different implementations
    */
    else if ...
    /*
    * check for other errors
    */

    SEE ALSO
    lockd(1M), statd(1M), chmod(2), close(2), creat(2), fcntl(2),
    creat64(2), open(2), pause(2), read(2), stat(2), wait(2), write
    (2),
    unistd(5).

    STANDARDS CONFORMANCE
    lockf(): SVID2, SVID3, XPG2
    Prince Al, Oct 27, 2009
    #15
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Christopher T King

    threads: not locking read-only objects

    Christopher T King, Aug 6, 2004, in forum: Python
    Replies:
    3
    Views:
    279
    Heiko Wundram
    Aug 7, 2004
  2. Timasmith
    Replies:
    4
    Views:
    445
    Bjorn Borud
    Nov 1, 2006
  3. Replies:
    1
    Views:
    879
    Juha Laiho
    Jun 18, 2007
  4. Ladislav Andel
    Replies:
    0
    Views:
    274
    Ladislav Andel
    Aug 8, 2007
  5. Chris Mellon
    Replies:
    0
    Views:
    397
    Chris Mellon
    Aug 8, 2007
Loading...

Share This Page