flock user defined function

Started by Chris Goughnouralmost 22 years ago5 messagesgeneral
Jump to latest
#1Chris Goughnour
cgoughnour@hotp.com

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);
}

#2Martijn van Oosterhout
kleptog@svana.org
In reply to: Chris Goughnour (#1)
Re: flock user defined function

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/

Show quoted text

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.

#3Tom Lane
tgl@sss.pgh.pa.us
In reply to: Chris Goughnour (#1)
Re: flock user defined function

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

#4Doug McNaught
doug@mcnaught.org
In reply to: Martijn van Oosterhout (#2)
Re: flock user defined function

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

#5Chris Goughnour
cgoughnour@hotp.com
In reply to: Tom Lane (#3)
Re: flock user defined function

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. :-)

Show quoted text

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