Thread: 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.
Attachment
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