Thread: flock user defined function

flock user defined function

From
Chris Goughnour
Date:
I'm trying to write two C language user defined functions, lockfile() and
unlockfile(), that call flock using LOCK_EX and LOCK_UN respectively.  If I
call lockfile from a first psql process it returns successfully.  Calling
lockfile from a second psql process blocks. However, when I call unlockfile
from the first psql process, the second process still blocks.  The lockfile
call from the second psql proccess doesn't return until I kill the first
psql process.
Any suggestions? Thanks in advance.
Chris Goughnour

PG_FUNCTION_INFO_V1(lockFile);
Datum lockFile(PG_FUNCTION_ARGS){
        text *t=PG_GETARG_TEXT_P(0);
        char *path=palloc(VARSIZE(t)-VARHDRSZ+1);
        int fileHandle,status;
        memcpy((void *)path,(void *)VARDATA(t),VARSIZE(t)-VARHDRSZ);
        path[VARSIZE(t)-VARHDRSZ]=0;
        fileHandle=open((const char *)path,O_RDONLY);
        if(fileHandle==-1){
                PG_RETURN_INT32(-1);
        }
        if(flock(fileHandle,LOCK_EX)==-1){
                PG_RETURN_INT32(-1);
        }
        PG_RETURN_INT32(0);
}

PG_FUNCTION_INFO_V1(unlockFile);
Datum unlockFile(PG_FUNCTION_ARGS){
        text *t=PG_GETARG_TEXT_P(0);
        char *path=palloc(VARSIZE(t)-VARHDRSZ+1);
        int fileHandle;
        memcpy((void *)path,(void *)VARDATA(t),VARSIZE(t)-VARHDRSZ);
        path[VARSIZE(t)-VARHDRSZ]=0;
        fileHandle=open((const char *)path,O_RDONLY);
        if(fileHandle==-1){
                PG_RETURN_INT32(-1);
        }
        if(flock(fileHandle,LOCK_UN)==-1){
                PG_RETURN_INT32(-1);
        }
        PG_RETURN_INT32(0);
}


Re: flock user defined function

From
Martijn van Oosterhout
Date:
On Tue, Jun 22, 2004 at 02:49:27PM -0700, Chris Goughnour wrote:
> I'm trying to write two C language user defined functions, lockfile() and
> unlockfile(), that call flock using LOCK_EX and LOCK_UN respectively.  If I
> call lockfile from a first psql process it returns successfully.  Calling
> lockfile from a second psql process blocks. However, when I call unlockfile
> from the first psql process, the second process still blocks.  The lockfile
> call from the second psql proccess doesn't return until I kill the first
> psql process.
> Any suggestions? Thanks in advance.
> Chris Goughnour

<snip>

Where do you close the file? That might cause some issues.
--
Martijn van Oosterhout   <kleptog@svana.org>   http://svana.org/kleptog/
> Patent. n. Genius is 5% inspiration and 95% perspiration. A patent is a
> tool for doing 5% of the work and then sitting around waiting for someone
> else to do the other 95% so you can sue them.

Attachment

Re: flock user defined function

From
Tom Lane
Date:
Chris Goughnour <cgoughnour@hotp.com> writes:
> Any suggestions? Thanks in advance.

I believe locks are associated with file descriptors (what you're
miscalling a handle).  The unlock function cannot release a lock
that is held via a different descriptor.  What it needs to be doing
is closing the descriptor that lockFile opened.  This would also
solve the rather serious descriptor-leak problem you've got.

            regards, tom lane

Re: flock user defined function

From
Doug McNaught
Date:
Martijn van Oosterhout <kleptog@svana.org> writes:

> On Tue, Jun 22, 2004 at 02:49:27PM -0700, Chris Goughnour wrote:
>> I'm trying to write two C language user defined functions, lockfile() and
>> unlockfile(), that call flock using LOCK_EX and LOCK_UN respectively.  If I
>> call lockfile from a first psql process it returns successfully.  Calling
>> lockfile from a second psql process blocks. However, when I call unlockfile
>> from the first psql process, the second process still blocks.  The lockfile
>> call from the second psql proccess doesn't return until I kill the first
>> psql process.
>> Any suggestions? Thanks in advance.
>> Chris Goughnour
>
> <snip>
>
> Where do you close the file? That might cause some issues.

Yeah, it's generally best not to call LOCK_UN at all, but just to
close the file (which will release the locks).  Otherwise, if you are
using stdio, you can get a situation where the file is unlocked but
its stdio buffer has not been flushed, leading to the corruption you
were trying to avoid by locking the file...

-Doug

Re: flock user defined function

From
Chris Goughnour
Date:
Thanks. Yeah, I figured that out after Martijn's response. I'm just
returning the file descriptor from lockFile, passing it to unlockFile and
closing the descriptor there.  It works fine now. Thanks for edifying a
clueless novice such as myself. :-)
> Chris Goughnour <cgoughnour@hotp.com> writes:
>> Any suggestions? Thanks in advance.
>
> I believe locks are associated with file descriptors (what you're
> miscalling a handle).  The unlock function cannot release a lock
> that is held via a different descriptor.  What it needs to be doing
> is closing the descriptor that lockFile opened.  This would also
> solve the rather serious descriptor-leak problem you've got.
>
> regards, tom lane