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 -- [email protected]
To unsubscribe send an email to [email protected]