Changeset: 16d91b1f3cff for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/16d91b1f3cff Modified Files: common/utils/mutils.c Branch: Sep2022 Log Message:
Reuse file descriptor when unlocking a file in MT_lockf. This was already done like that on Windows, now also elsewhere. Also, updating the linked list for this is a critical section. diffs (126 lines): diff --git a/common/utils/mutils.c b/common/utils/mutils.c --- a/common/utils/mutils.c +++ b/common/utils/mutils.c @@ -468,9 +468,17 @@ MT_lockf(const char *filename, int mode) wchar_t *wfilename; int fildes; } *lockedfiles; + static CRITICAL_SECTION cs; + static bool inited = false; struct lockedfiles **fpp, *fp; wchar_t *wfilename; + if (!inited) { + /* here we're still running single threaded */ + InitializeCriticalSection(&cs); + inited = true; /* only time this is changed */ + } + if ((wfilename = utf8towchar(filename)) == NULL) return -2; ov = (OVERLAPPED) {0}; @@ -483,19 +491,21 @@ MT_lockf(const char *filename, int mode) #endif if (mode == F_ULOCK) { + EnterCriticalSection(&cs); for (fpp = &lockedfiles; (fp = *fpp) != NULL; fpp = &fp->next) { if (wcscmp(fp->wfilename, wfilename) == 0) { + *fpp = fp->next; + LeaveCriticalSection(&cs); free(fp->wfilename); fd = fp->fildes; fh = (HANDLE) _get_osfhandle(fd); - fp = *fpp; - *fpp = fp->next; free(fp); ret = UnlockFileEx(fh, 0, 1, 0, &ov); free(wfilename); return ret ? 0 : -1; } } + LeaveCriticalSection(&cs); /* didn't find the locked file, try opening the file * directly */ fh = CreateFileW(wfilename, @@ -542,8 +552,10 @@ MT_lockf(const char *filename, int mode) if ((fp = malloc(sizeof(*fp))) != NULL) { fp->wfilename = wfilename; fp->fildes = fd; + EnterCriticalSection(&cs); fp->next = lockedfiles; lockedfiles = fp; + LeaveCriticalSection(&cs); } else { free(wfilename); } @@ -752,6 +764,8 @@ lockf(int fd, int cmd, off_t len) } #endif +#include <pthread.h> + #ifndef O_TEXT #define O_TEXT 0 #endif @@ -763,19 +777,57 @@ lockf(int fd, int cmd, off_t len) int MT_lockf(const char *filename, int mode) { - int fd = open(filename, O_CREAT | O_RDWR | O_TEXT | O_CLOEXEC, MONETDB_MODE); + static struct lockfile { + char *filename; + int fd; + struct lockfile *next; + } *lockfiles = NULL; + static pthread_mutex_t cs = PTHREAD_MUTEX_INITIALIZER; + struct lockfile *fp; + int fd; + off_t seek; + + if (mode == F_ULOCK) { + pthread_mutex_lock(&cs); + for (struct lockfile **fpp = &lockfiles; (fp = *fpp) != NULL; fpp = &fp->next) { + if (strcmp(fp->filename, filename) == 0) { + *fpp = fp->next; + pthread_mutex_unlock(&cs); + free(fp->filename); + fd = fp->fd; + free(fp); + seek = lseek(fd, 4, SEEK_SET); + int ret = lockf(fd, mode, 1); + (void) lseek(fd, seek, SEEK_SET); /* move seek pointer back */ + /* do not close fd, it is closed by caller */ + return ret; /* 0 if unlock successful, -1 if not */ + } + } + } + fd = open(filename, O_CREAT | O_RDWR | O_TEXT | O_CLOEXEC, MONETDB_MODE); if (fd < 0) return -2; - if (lseek(fd, 4, SEEK_SET) >= 0 && + if ((seek = lseek(fd, 4, SEEK_SET)) >= 0 && lockf(fd, mode, 1) == 0) { if (mode == F_ULOCK || mode == F_TEST) { close(fd); return 0; } + if ((fp = malloc(sizeof(*fp))) != NULL) { + if ((fp->filename = strdup(filename)) != NULL) { + fp->fd = fd; + pthread_mutex_lock(&cs); + fp->next = lockfiles; + lockfiles = fp; + pthread_mutex_unlock(&cs); + } else { + free(fp); + } + } /* do not close else we lose the lock we want */ - (void) lseek(fd, 0, SEEK_SET); /* move seek pointer back */ + (void) lseek(fd, seek, SEEK_SET); /* move seek pointer back */ return fd; } close(fd); _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org