[rddsql/SQLBASE MT] 2026-09-29 21:37 UTC+0200 Aleksander Czajczynski (hb fki.pl)

100 views
Skip to first unread message

Aleksander Czajczynski

unread,
Sep 29, 2026, 4:22:41 PMSep 29
to harbou...@googlegroups.com
2026-09-29 21:37 UTC+0200 Aleksander Czajczynski (hb fki.pl)
* contrib/rddsql/hbrddsql.h
* contrib/rddsql/sqlbase.c
* reshaped SQLBASE RDD for multi-threading. There are
now separate connection tables for each thread and also
a global one (either for compatibility with old SQLBASE
or scenarios that fit for serialized RDBMS access).
SQLMIX should inherit these features, as it didn't have
non MT-safe elements.

+ RDDI_CONNECT method now supports "THREAD:" and "GLOBAL:"
prefixes in the driver specifier, for example:
RDDINFO( RDDI_CONNECT, {"THREAD:SQLITE3", "..."} )

NOTE: "GLOBAL:" mode is the current default when prefix is
not specified, still that may change in the future.
If you want to keep connections in global state please
add explicit "GLOBAL:" prefix.

* RDDIINFO( RDDI_CONNECTION, <nConnection> ) is now per-thread
isolated value. Also after spawning a new thread, to access
already established global connection, the value has to be
assigned again.
[INCOMPATIBLE]

+ added pSDD->EngineFlags bit-flags (SDDNODE struct):
SQLDD_EFLAG_CAN_CREATE - driver supports creating (temp)table
SQLDD_EFLAG_MT_AWARE - driver is optimized/safe for MT mode

* contrib/sddfb/core.c
* contrib/sddmy/core.c
* contrib/sddoci/core.c
* marked as non-MT aware, per driver Mutex will
be used for such connections in global scope.
To protect SQL Transactions retain .prg mutexes,
which you should already have in place if been
using SDD in MT.

! dbCreate()/dbGoto() GPF is fixed by _not_ declaring
SQLDD_EFLAG_CAN_CREATE. DBCreate() now falls back
to SDDNULL as parent driver when MYSQL, OCILIB,
FIREBIRD are in focus.

* contrib/sddodbc/core.c
* contrib/sddpg/core.c
* marked as non-MT aware, can be used in global
scope as they have always been. These are the next
candidates for MT conversion.

* contrib/sddsqlt3/core.c
* multi-threading is now enabled in SQLite SDD.
That is as long as it is version 3.6.4+ and was compiled
with SQLITE_THREADSAFE=[1 or 2]. Any other builds are
detected as unsafe using runtime sqlite3_threadsafe()
call.

+ implemented RDDI_INSERTID: it is mapped to SQLite
ROWID of last inserted row, that should also
transparently map to PRIMARY KEY if it's defined
as single integer column.

+ with SQLite >= 3.6.4 SDD now uses sqlite_open_v2()
call to open a connection

+ contrib/sddsqlt3/tests/mttest.prg
+ small stress-test for SQLite multi-threading, testing
both THREAD: and GLOBAL: spaces. On-file multi-threading
is quite slow, but the tests can also run in-memory.
Specify any parameter to switch this mode: ./mttest mem

==

Hello!

SDD not being MT aware was blocking me from implementing some
extensions, so here goes the effort. I did it as IMHO simplest
modification possible to the codebase, but it is very concurrent by
design. Connection tables are number ordered, reallocated, etc., not
using pointer/handles.

I have an additional idea floting of either scoping thread local
connection number (instead of current bitmasking). It may limit on the
number of threads though if they are short-lived.

Can be outlined as follows:

#define CONNECTION_MAX 65535
#define CONN_THREAD_DIV 100000UL

#define CONN_IS_THREAD( h ) ( ( h ) > CONNECTION_MAX )
#define CONN_INDEX( h ) ( ( h ) % CONN_THREAD_DIV ) /*
1-based */
#define CONN_OWNER( h ) ( ( h ) / CONN_THREAD_DIV )
#define CONN_MAKE( thr, ix ) ( ( HB_ULONG ) ( thr ) * CONN_THREAD_DIV +
( ix ) )

/* returns index (1-based) or 0 with error set */
static HB_ULONG sddThreadConnIndex( HB_ULONG ulConn )
{
if( CONN_OWNER( ulConn ) != ( HB_ULONG ) hb_threadNo() )
{
hb_errRT_SQLBASE( EG_OPEN, ESQLDD_NOTCONNECTED,
"Connection belongs to another thread", NULL );
return 0;
}
return CONN_INDEX( ulConn );
}

Then something might be applied in RDDI_ space to allow moving between
thread<->global spaces.

Or leave this alone, another idea is to create supplemental
SQLBASEH/SQLMIXH pair of RDDs (fiddling a bit with inheritance), that
will no longer use C arrays to catalog connections, but rather GC
collected pointers to specify a connection. Such GC-parptr can then
store additional info about thread it belongs or not. This could keep
SQLBASE/SQLMIX as is, summing, so would satisfy many use-cases. Specific
SDD's don't seem to need modifications for this to happen.

Best regards, Aleksander


Reply all
Reply to author
Forward
0 new messages