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

Reply via email to