Обсуждение: flock user defined function
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);
}
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.
Вложения
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
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
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