Changeset: b735da1fd959 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/b735da1fd959
Modified Files:
        sql/backends/monet5/vaults/csv/CMakeLists.txt
        testing/Mtest.py.in
Branch: default
Log Message:

Merge with Aug2024 branch.


diffs (truncated from 356 to 300 lines):

diff --git a/clients/mapiclient/curl-stream.h b/clients/mapiclient/curl-stream.h
--- a/clients/mapiclient/curl-stream.h
+++ b/clients/mapiclient/curl-stream.h
@@ -1,3 +1,15 @@
+/*
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0.  If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * Copyright 2024, 2025 MonetDB Foundation;
+ * Copyright August 2008 - 2023 MonetDB B.V.;
+ * Copyright 1997 - July 2008 CWI.
+ */
+
 #include <curl/curl.h>
 
 #ifndef CURL_WRITEFUNC_ERROR
diff --git a/clients/mapiclient/iconv-stream.h 
b/clients/mapiclient/iconv-stream.h
--- a/clients/mapiclient/iconv-stream.h
+++ b/clients/mapiclient/iconv-stream.h
@@ -1,3 +1,15 @@
+/*
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0.  If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * Copyright 2024, 2025 MonetDB Foundation;
+ * Copyright August 2008 - 2023 MonetDB B.V.;
+ * Copyright 1997 - July 2008 CWI.
+ */
+
 #include <iconv.h>
 
 struct ic_priv_t {
diff --git a/testing/Mtest.py.in b/testing/Mtest.py.in
--- a/testing/Mtest.py.in
+++ b/testing/Mtest.py.in
@@ -1357,7 +1357,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'), 
dbg=env.get('DBG'))
+                    pSrvr = ServerClass(splitcommand(env['exe']['mserver5'][1] 
+[f'--dbpath={LogDBdir}'] + vaultopt + mserver5_opts), open(os.devnull, 'w'), 
open(os.devnull, 'w'), par['TIMEOUT'], os.path.join(LogDBdir, '.started'), 
TSTDB, dbg=env.get('DBG'))
                     pSrvr.LaunchIt()
                     pSrvr.terminate()
         if not os.path.exists(TSTTRGDIR):
@@ -1405,6 +1405,7 @@ def PerformDir(env, testdir, testlist, t
                                         openutf8(os.path.join(TSTTRGDIR, 
'SingleServer.err'), 'a'),
                                         0,
                                         pollfile,
+                                        TSTDB,
                                         inmem=inmem,
                                         dbg=env.get('DBG'))
                     os.chdir(TSTTRGDIR)
@@ -1419,9 +1420,14 @@ def PerformDir(env, testdir, testlist, t
                                                 hostname=HOST,
                                                 port=int(pSrvr.port),
                                                 database=TSTDB,
-                                                autocommit=True)
+                                                autocommit=True,
+                                                connect_timeout=1.0)
                     except KeyboardInterrupt:
                         raise
+                    except ConnectionRefusedError:
+                        print('\nConnection refused.\n')
+                        FdOut = FdErr = F_FAIL
+                        break
                     except:
                         pass
                     else:
@@ -2633,16 +2639,7 @@ def reallyKill(proc):
     # not called on Windows
     killchildren(proc.pid, getkids())
 
-def killProc(proc, outfile = None, cmd = None):
-    if type(cmd) is type([]):
-        cmd = ' '.join(cmd)
-    if procdebug:
-        print('timeout for process %d (%s)' % (proc.pid, cmd))
-    if outfile is not None and cmd is not None:
-        try:
-            outfile.write('\n!Mtimeout: Timeout: %s\n' % cmd)
-        except (ValueError, IOError):
-            print('cannot write timeout message ' + cmd)
+def stacktrace(proc, outfile):
     if os.name == "nt":
         sym = ''
         if os.path.exists(r'c:\Program Files\Debugging Tools for Windows 
(x64)\cdb.exe'):
@@ -2657,14 +2654,22 @@ def killProc(proc, outfile = None, cmd =
             cdb = None
         if cdb:
             with process.Popen([cdb, '-pv', '-p', str(proc.pid),
-                                '-y', 
'%scache*;srv*http://msdl.microsoft.com/download/symbols' % sym, '-lines', 
'-c', '~*kP;!locks;q'],
+                                '-y', 
f'{sym}cache*;srv*http://msdl.microsoft.com/download/symbols', '-lines', '-c', 
'~*kP;!locks;q'],
                                stdout=process.PIPE, text=True) as p:
                 out, err = p.communicate()
         else:
             out = ''
+    elif platform.system() == 'Darwin':
+        try:
+            with process.Popen(['lldb', '--attach-pid', str(proc.pid), 
'--batch', '--one-line', 'bt all'], stdout=process.PIPE, text=True) as p:
+                out, err = p.communicate()
+        except KeyboardInterrupt:
+            raise
+        except:
+            out = ''
     else:
         try:
-            with process.Popen(['gdb', '-p', str(proc.pid), '-batch', '-ex', 
'thread apply all bt full', '-ex', 'call dump_threads()'], stdout=process.PIPE,
+            with process.Popen(['gdb', '-p', str(proc.pid), '-batch', '-ex', 
'thread apply all bt full'], stdout=process.PIPE,
                                text=True) as p:
                 try:
                     # gdb sometimes hangs when trying to get the stack
@@ -2682,15 +2687,32 @@ def killProc(proc, outfile = None, cmd =
             out = ''
     if outfile is not None and out:
         try:
-            outfile.write('\n%s\n' % out)
+            outfile.write(f'\n{out}\n')
         except (ValueError, IOError):
             print('cannot write stack trace')
             print(out)
+
+def killProc(proc, outfile=None, cmd=None, psrvr=None):
+    if type(cmd) is type([]):
+        cmd = ' '.join(cmd)
+    if procdebug:
+        print('timeout for process %d (%s)' % (proc.pid, cmd))
+    if outfile is not None and cmd is not None:
+        try:
+            outfile.write('\n!Mtimeout: Timeout: %s\n' % cmd)
+        except (ValueError, IOError):
+            print('cannot write timeout message ' + cmd)
+    stacktrace(proc, outfile)
     proc.killed = True
     if proc.onechild:
-        if procdebug:
-            print('killProc: calling proc.kill() on PID %d' % proc.pid)
-        proc.kill()
+        if psrvr is not None and psrvr.proc is proc:
+            if procdebug:
+                print(f'killProc: calling psrvr.terminate() on PID {proc.pid}')
+            psrvr.terminate()
+        else:
+            if procdebug:
+                print(f'killProc: calling proc.kill() on PID {proc.pid}')
+            proc.kill()
     elif os.name == 'nt':
         if procdebug:
             print('killProc: starting process "taskkill" "/F" "/T" "/PID" 
"%s"\n' % str(proc.pid))
@@ -2705,7 +2727,7 @@ def killProc(proc, outfile = None, cmd =
         killchildren(proc.pid)
 
 class ServerClass:
-    def __init__(self, cmd, TestOut, TestErr, TimeOut, pollfile, inmem=False, 
dbg=None):
+    def __init__(self, cmd, TestOut, TestErr, TimeOut, pollfile, dbname, 
inmem=False, dbg=None):
         self.proc = None
         self.timer = None
         self.outfile = TestOut
@@ -2717,13 +2739,16 @@ class ServerClass:
         self.pollfile = pollfile
         self.inmem = inmem
         self.dbg = dbg
+        self.dbname = dbname
+        self.running = None
+        self.lock = threading.Lock()
 
     def poll(self):
         return self.proc.poll()
 
     def terminate(self):
         self.timer.cancel()
-        t = Timer(60, killProc, args = [self.proc, self.errfile, self.cmd])
+        t = Timer(60, killProc, args=[self.proc, self.errfile, self.cmd, self])
         t.start()
         if os.name == 'nt':
             self.proc.send_signal(signal.CTRL_BREAK_EVENT)
@@ -2737,11 +2762,53 @@ class ServerClass:
         self.outfile.close()
         self.errfile.close()
 
+    def start(self, timeout):
+        self.running = Timer(timeout, self.stopsessions, [])
+        self.running.start()
+
+    def stop(self):
+        if self.lock.acquire():
+            if self.running:
+                self.running.cancel()
+                self.running = None
+            self.lock.release()
+
     def sendusr1(self):
         if os.name != 'nt':
+            if procdebug:
+                print(f'sendusr1: sending USR1 signal to {self.proc.pid}')
             self.proc.send_signal(signal.SIGUSR1)
             time.sleep(1)
 
+    def stacktrace(self):
+        stacktrace(self.proc, self.outfile)
+        self.sendusr1()
+
+    def stopsessions(self):
+        if self.lock.acquire(blocking=False):
+            if self.running is not None:
+                self.stacktrace()
+                try:
+                    dbh = pymonetdb.connect(username='monetdb',
+                                            password='monetdb',
+                                            hostname=HOST,
+                                            port=int(self.port),
+                                            database=self.dbname,
+                                            connect_timeout=1.0)
+                    crs = dbh.cursor()
+                    crs.execute('select sessionid from sys.sessions() where 
sessionid <> sys.current_sessionid()')
+                    ids = crs.fetchall()
+                    for x in ids:
+                        if procdebug:
+                            print(f'stopping session {x[0]}')
+                            crs.execute(f'call sys.stopsession({x[0]})')
+                    if procdebug and not ids:
+                        print('no sessions to stop')
+                except:
+                    pass
+                self.running = None
+            self.lock.release()
+
     def LaunchIt(self):
         global setpgrp
 
@@ -2781,11 +2848,10 @@ class ServerClass:
             proc.stderr = process._BufferedPipe(proc.stderr)
         proc.killed = False
         proc.onechild = True
-        t = Timer(self.timeout, killProc, args = [proc, self.errfile, 
self.cmd])
+        self.timer = Timer(self.timeout, killProc, args=[proc, self.errfile, 
self.cmd, self])
         if self.timeout > 0:
-            t.start()
+            self.timer.start()
         self.proc = proc
-        self.timer = t
 
         port = None
         self.port = None
@@ -2795,7 +2861,7 @@ class ServerClass:
                 if proc.returncode is not None:
                     # exited
                     proc.wait()
-                    t.cancel()
+                    self.timer.cancel()
                     return
                 if os.path.exists(self.pollfile):
                     break
@@ -2822,14 +2888,14 @@ class ServerClass:
             else:
                 proc.terminate()
             proc.wait()
-            t.cancel()
+            self.timer.cancel()
             return
         self.started = True
         self.port = port
 
 ### LaunchIt(cmd, TestIn, TestOut, TestErr, TimeOut, pollfile, port) #
 
-def RunIt(cmd, onechild, TestIn, TestOut, TestErr, TimeOut) :
+def RunIt(cmd, onechild, TestIn, TestOut, TestErr, TimeOut, pSrvr) :
     global setpgrp
     if type(TestIn) is type(''):
         TestInput = TestIn
@@ -2845,7 +2911,7 @@ def RunIt(cmd, onechild, TestIn, TestOut
                        stderr=TestErr, text=True) as proc:
         proc.killed = False
         proc.onechild = onechild
-        t = Timer(TimeOut, killProc, args = [proc, TestErr, cmd])
+        t = Timer(TimeOut, killProc, args = [proc, TestErr, cmd, pSrvr])
         try:
             t.start()
             # since both stdout and stderr are redirected to files,
@@ -2982,7 +3048,7 @@ def DoIt(env, SERVER, CALL, TST, EXT, Te
                     Srvr.extend(openutf8(TST + '.options5').read().split())
                 Srvr.extend(mserver5_opts)
                 Srvr.extend(options)
-                pSrvr = ServerClass(Srvr, SrvrOut, SrvrErr, TIMEOUT, 
os.path.join(dbpath, '.started'), dbg=env.get('DBG'))
+                pSrvr = ServerClass(Srvr, SrvrOut, SrvrErr, TIMEOUT, 
os.path.join(dbpath, '.started'), TSTDB, dbg=env.get('DBG'))
                 pSrvr.LaunchIt()
                 if pSrvr.port is None:
                     print('\nFailed to start server.\n')
@@ -2990,8 +3056,9 @@ def DoIt(env, SERVER, CALL, TST, EXT, Te
                 os.environ['MAPIPORT'] = env['MAPIPORT'] = pSrvr.port
                 SetExecEnv(exe,pSrvr.port,verbosity > 1)
             else:
-                PSRVR.timer.settimeout(TIMEOUT)
-                PSRVR.timer.start()
+                PSRVR.start(TIMEOUT)
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to