Changeset: 4469ecb45f6d for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/4469ecb45f6d
Branch: default
Log Message:

Merge with Sep2022 branch.


diffs (277 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);
diff --git a/sql/test/concurrent/Tests/read-segment-after-free.timeout 
b/sql/test/concurrent/Tests/read-segment-after-free.timeout
new file mode 100644
--- /dev/null
+++ b/sql/test/concurrent/Tests/read-segment-after-free.timeout
@@ -0,0 +1,1 @@
+2
diff --git a/sql/test/copy/Tests/nonutf8.py b/sql/test/copy/Tests/nonutf8.SQL.py
rename from sql/test/copy/Tests/nonutf8.py
rename to sql/test/copy/Tests/nonutf8.SQL.py
--- a/sql/test/copy/Tests/nonutf8.py
+++ b/sql/test/copy/Tests/nonutf8.SQL.py
@@ -19,9 +19,12 @@ with process.client('sql', text=False, s
     retcode = c.returncode
 
     if retcode == 0:
-        sys.stderr.write("Expected nonzero return code")
+        print(f"Expected nonzero return code, received {retcode}",
+              file=sys.stderr)
     if not err or b'invalid start of UTF-8 sequence' not in err:
-        sys.stderr.write("Expected stderr to contain 'invalid start of UTF-8 
sequence'")
+        print("Expected stderr to contain 'invalid start of UTF-8 sequence'",
+              file=sys.stderr)
+        print(f"Received: {err}", file=sys.stderr)
 
 # input is a byte string because it contains broken utf-8
 INPUT2 = b"""
@@ -34,9 +37,12 @@ with process.client('sql', text=False, s
     retcode = c.returncode
 
     if retcode == 0:
-        sys.stderr.write("Expected nonzero return code")
+        print(f"Expected nonzero return code, received {retcode}",
+              file=sys.stderr)
     if not err or b'input not properly encoded UTF-8' not in err:
-        sys.stderr.write("Expected stderr to contain 'input not properly 
encoded UTF-8'")
+        print("Expected stderr to contain 'input not properly encoded UTF-8'",
+              file=sys.stderr)
+        print(f"Received: {err}", file=sys.stderr)
 
 with SQLTestCase() as tc:
     tc.connect(username="monetdb", password="monetdb")
diff --git a/testing/Mtest.py.in b/testing/Mtest.py.in
--- a/testing/Mtest.py.in
+++ b/testing/Mtest.py.in
@@ -1355,7 +1355,7 @@ def PerformDir(env, testdir, testlist, t
                 else:
                     vaultopt = []
                 if not oneserver:
-                    pSrvr = 
ServerClass(splitcommand(env['exe']['mserver5'][1]) + ['--dbpath=%s' % 
LogDBdir] + vaultopt + mserver5_opts, open(os.devnull, 'w'), open(os.devnull, 
'w'), par['TIMEOUT'], os.path.join(LogDBdir, '.started'))
+                    pSrvr = ServerClass(splitcommand(env['exe']['mserver5'][1] 
+['--dbpath=%s' % LogDBdir] + vaultopt + mserver5_opts), open(os.devnull, 'w'), 
open(os.devnull, 'w'), par['TIMEOUT'], os.path.join(LogDBdir, '.started'), 
dbg=env.get('DBG'))
                     pSrvr.LaunchIt()
                     pSrvr.terminate()
         if not os.path.exists(TSTTRGDIR):
@@ -1401,7 +1401,8 @@ def PerformDir(env, testdir, testlist, t
                                         openutf8(os.path.join(TSTTRGDIR, 
'SingleServer.err'), 'a'),
                                         0,
                                         pollfile,
-                                        inmem=inmem)
+                                        inmem=inmem,
+                                        dbg=env.get('DBG'))
                     os.chdir(TSTTRGDIR)
                     pSrvr.LaunchIt()
                     if pSrvr.port is None:
@@ -2574,7 +2575,7 @@ def killProc(proc, outfile = None, cmd =
         killchildren(proc.pid)
 
 class ServerClass:
-    def __init__(self, cmd, TestOut, TestErr, TimeOut, pollfile, inmem=False):
+    def __init__(self, cmd, TestOut, TestErr, TimeOut, pollfile, inmem=False, 
dbg=None):
         self.proc = None
         self.timer = None
         self.outfile = TestOut
@@ -2585,6 +2586,7 @@ class ServerClass:
         self.timeout = TimeOut
         self.pollfile = pollfile
         self.inmem = inmem
+        self.dbg = dbg
 
     def poll(self):
         return self.proc.poll()
@@ -2614,25 +2616,31 @@ class ServerClass:
         if procdebug:
             print('LaunchIt: starting process "%s" (inpipe)\n' % '" 
"'.join(self.cmd))
         setpgrp = True
-        outfile = self.outfile
+        stdin = open(os.devnull)
+        stdout = self.outfile
+        stderr = self.errfile
+        cmd = self.cmd
         if self.inmem:
-            outfile = process.PIPE
+            stdout = process.PIPE
         elif self.pollfile:
             try:
                 os.unlink(self.pollfile)
             except OSError:
                 pass
+            if self.dbg:
+                stdin = stdout = stderr = None
+                cmd = splitcommand(self.dbg) + self.cmd
         else:
-            outfile = process.PIPE
+            stdout = process.PIPE
         if os.name == "nt":
-            proc = process.Popen(self.cmd, stdin=open(os.devnull), 
stdout=outfile,
-                                 stderr=self.errfile, text=True,
+            proc = process.Popen(cmd, stdin=stdin, stdout=stdout,
+                                 stderr=stderr, text=True,
                                  
creationflags=process.CREATE_NEW_PROCESS_GROUP)
         else:
-            proc = process.Popen(self.cmd, stdin=open(os.devnull), 
stdout=outfile,
-                                 stderr=self.errfile, text=True)
+            proc = process.Popen(cmd, stdin=stdin, stdout=stdout,
+                                 stderr=stderr, text=True)
         # maybe buffer output as it comes to avoid deadlock
-        if outfile == process.PIPE:
+        if stdout == process.PIPE:
             proc.stdout = process._BufferedPipe(proc.stdout)
         if self.errfile == process.PIPE:
             proc.stderr = process._BufferedPipe(proc.stderr)
@@ -2831,7 +2839,7 @@ def DoIt(env, SERVER, CALL, TST, EXT, Te
                 if os.path.isfile(TST + '.options5'):
                     Srvr.extend(openutf8(TST + '.options5').read().split())
                 Srvr.extend(mserver5_opts)
-                pSrvr = ServerClass(Srvr, SrvrOut, SrvrErr, TIMEOUT, 
os.path.join(dbpath, '.started'))
+                pSrvr = ServerClass(Srvr, SrvrOut, SrvrErr, TIMEOUT, 
os.path.join(dbpath, '.started'), dbg=env.get('DBG'))
                 pSrvr.LaunchIt()
                 if pSrvr.port is None:
                     print('\nFailed to start server.\n')
@@ -3658,10 +3666,6 @@ def main(argv) :
         env['setMONETDB_MOD_PATH'] = eval(dft['setMONETDB_MOD_PATH'])
     else:
         env['setMONETDB_MOD_PATH'] = ''
-    if 'DBG' in env:
-        env['setDBG'] = env['DBG']
-    else:
-        env['setDBG'] = ''
 
     #TODO:
     ## in case of inconsistencies, try to fallback to "save" settings
@@ -3847,8 +3851,8 @@ def main(argv) :
             SOCK = ""
 
         exe = {}
-        exe['mserver5']       = CheckExec('mserver5')     , '%s mserver5 
--debug=%s --set gdk_nr_threads=%s %s --set mapi_listenaddr=all --set 
mapi_port=0 %s %s' % \
-                                                               (env['setDBG'], 
env['GDK_DEBUG'], env['GDK_NR_THREADS'], env['setMONETDB_MOD_PATH'], SOCK, not 
nomito and '--forcemito' or '')
+        exe['mserver5']       = CheckExec('mserver5')     , 'mserver5 
--debug=%s --set gdk_nr_threads=%s %s --set mapi_listenaddr=all --set 
mapi_port=0 %s %s' % \
+                                                               
(env['GDK_DEBUG'], env['GDK_NR_THREADS'], env['setMONETDB_MOD_PATH'], SOCK, not 
nomito and '--forcemito' or '')
         exe['ruby_client']   = CheckExec(env['RUBYCLIENT'].split(None, 1)[0])  
 , '%s %s' % (env['RUBYCLIENT'], '${PORT}')
         exe['MAL_Client']    = CheckExec(env['MALCLIENT'].split(None, 1)[0])  
, '%s --host=%s --port=%s' % (env['MALCLIENT'], HOST, '${PORT}')
         exe['SQL_Client']    = CheckExec(env['SQLCLIENT'].split(None, 1)[0])   
, '%s -i -e --host=%s --port=%s' % (env['SQLCLIENT'], HOST, '${PORT}')
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to