Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!usc!cs.utexas.edu!uunet!cs.dal.ca!aucs!850153d From: 850153d@aucs.uucp (Jules d'Entremont) Newsgroups: comp.unix.wizards Subject: Record locking vs. buffered I/O Keywords: fcntl fread fwrite Message-ID: <1989Nov12.192441.9270@aucs.uucp> Date: 12 Nov 89 19:24:41 GMT Reply-To: 850153d@aucs.UUCP (Jules d'Entremont) Organization: School of Computer Science, Acadia Univ., Nova Scotia Lines: 65 I posted the following to comp.unix.questions but got no responses, so I'll try again here. I have the task of implementing a set of simple database routines. Since there may be multiple processes accessing the database simultaneously, we are using record locking (via the fcntl mechanism) to ensure data integrity. However, the manual warns that buffering as done in stdio may cause unexpected results. I understand that this results since the buffer may not be written to the file before the lock is released. To get around this, I use fflush() to flush the buffer before I release the lock. So my routine for writing to the database has the following skeleton: FILE *fptr; struct flock lock; data_record *datrec; lock.l_type = F_RDLCK; lock.l_whence = 0; lock.l_start = 0L; lock.l_len = 0L; fcntl(fileno(fptr), F_SETLK, &lock); /* Apply a shared lock */ /* fseek to the desired place in the file */ /* Code deleted */ lock.l_type = F_WRLCK; lock.l_whence = 1; fcntl(fileno(fptr), F_SETLK, &lock); /* Apply an exclusive lock */ fwrite((char *) datrec, sizeof(data_record), 1, fptr); fflush(fptr); lock.l_type = F_UNLCK; lock.l_whence = 0; fcntl(fileno(fptr), F_SETLK, &lock); /* Release all locks */ There is a similar routine for reading a record which contains the following code: fcntl(fileno(fptr), F_SETLK, &lock); /* Apply a shared lock */ /* fseek to the desired place in the file */ fread((char *) &datrec, sizeof(data_record), 1, fptr); lock.l_type = F_UNLCK; lock.l_whence = 0; fcntl(fileno(fptr), F_SETLK, &lock); /* Release all locks */ I think this scheme should work, but I am not convinced. Is there a problem with using buffered reads? Could the data read by fread() be incorrect because of the buffering being done? Should I even be using buffered I/O at all? (sizeof(data_record) = 24). This needs to work on an 80386 machine running AT&T SysV/386 Unix, but portable solutions would be preferred. Thanks for any help. -- Jules d'Entremont Acadia University, Wolfville, N.S., Canada BITNET/Internet 850153d@AcadiaU.CA UUCP {uunet | watmath | utai | garfield}!cs.dal.ca!aucs!850153d "To iterate is human, to recurse divine." - L. Peter Deutsch