Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 33 additions & 119 deletions ext/gvl_wrappers.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,17 @@
#ifndef __gvl_wrappers_h
#define __gvl_wrappers_h

#include <ruby/version.h>
#include <ruby/thread.h>

#ifdef RUBY_EXTCONF_H
# include RUBY_EXTCONF_H
#endif

#if RUBY_API_VERSION_MAJOR < 4
extern int ruby_thread_has_gvl_p(void);
#endif

#ifndef LIBPQ_HAS_CHUNK_MODE
typedef struct pg_cancel_conn PGcancelConn;
#endif
Expand Down Expand Up @@ -83,20 +88,35 @@ typedef struct pg_cancel_conn PGcancelConn;
}

#ifdef ENABLE_GVL_UNLOCK
#define DEFINE_GVLCB_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
struct gvl_wrapper_##name##_params params = { \
{FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname}, when_non_void((rettype)0) \
}; \
rb_thread_call_with_gvl(gvl_##name##_skeleton, &params); \
when_non_void( return params.retval; ) \
}
#if RUBY_API_VERSION_MAJOR >= 4 || defined(TRUFFLERUBY)
#define DEFINE_GVLCB_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
struct gvl_wrapper_##name##_params params = { \
{FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname}, when_non_void((rettype)0) \
}; \
rb_thread_call_with_gvl(gvl_##name##_skeleton, &params); \
when_non_void( return params.retval; ) \
}
#else
#define DEFINE_GVLCB_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
struct gvl_wrapper_##name##_params params = { \
{FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname}, when_non_void((rettype)0) \
}; \
if (ruby_thread_has_gvl_p()) { \
gvl_##name##_skeleton(&params); \
} else { \
rb_thread_call_with_gvl(gvl_##name##_skeleton, &params); \
} \
when_non_void( return params.retval; ) \
}
#endif
#else
#define DEFINE_GVLCB_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
when_non_void( return ) \
name( FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname ); \
}
#define DEFINE_GVLCB_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
when_non_void( return ) \
name( FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname ); \
}
#endif

#define GVL_TYPE_VOID(string)
Expand All @@ -121,50 +141,8 @@ typedef struct pg_cancel_conn PGcancelConn;

#define FOR_EACH_PARAM_OF_PQping(param)

#define FOR_EACH_PARAM_OF_PQexec(param) \
param(PGconn *, conn)

#define FOR_EACH_PARAM_OF_PQexecParams(param) \
param(PGconn *, conn) \
param(const char *, command) \
param(int, nParams) \
param(const Oid *, paramTypes) \
param(const char * const *, paramValues) \
param(const int *, paramLengths) \
param(const int *, paramFormats)

#define FOR_EACH_PARAM_OF_PQexecPrepared(param) \
param(PGconn *, conn) \
param(const char *, stmtName) \
param(int, nParams) \
param(const char * const *, paramValues) \
param(const int *, paramLengths) \
param(const int *, paramFormats)

#define FOR_EACH_PARAM_OF_PQprepare(param) \
param(PGconn *, conn) \
param(const char *, stmtName) \
param(const char *, query) \
param(int, nParams)

#define FOR_EACH_PARAM_OF_PQdescribePrepared(param) \
param(PGconn *, conn)

#define FOR_EACH_PARAM_OF_PQdescribePortal(param) \
param(PGconn *, conn)

#define FOR_EACH_PARAM_OF_PQclosePrepared(param) \
param(PGconn *, conn)

#define FOR_EACH_PARAM_OF_PQclosePortal(param) \
param(PGconn *, conn)

#define FOR_EACH_PARAM_OF_PQgetResult(param)

#define FOR_EACH_PARAM_OF_PQputCopyData(param) \
param(PGconn *, conn) \
param(const char *, buffer)

#define FOR_EACH_PARAM_OF_PQputCopyEnd(param) \
param(PGconn *, conn)

Expand All @@ -174,48 +152,8 @@ typedef struct pg_cancel_conn PGcancelConn;

#define FOR_EACH_PARAM_OF_PQnotifies(param)

#define FOR_EACH_PARAM_OF_PQsendQuery(param) \
param(PGconn *, conn)

#define FOR_EACH_PARAM_OF_PQsendQueryParams(param) \
param(PGconn *, conn) \
param(const char *, command) \
param(int, nParams) \
param(const Oid *, paramTypes) \
param(const char *const *, paramValues) \
param(const int *, paramLengths) \
param(const int *, paramFormats)

#define FOR_EACH_PARAM_OF_PQsendPrepare(param) \
param(PGconn *, conn) \
param(const char *, stmtName) \
param(const char *, query) \
param(int, nParams)

#define FOR_EACH_PARAM_OF_PQsendQueryPrepared(param) \
param(PGconn *, conn) \
param(const char *, stmtName) \
param(int, nParams) \
param(const char *const *, paramValues) \
param(const int *, paramLengths) \
param(const int *, paramFormats)

#define FOR_EACH_PARAM_OF_PQsendDescribePrepared(param) \
param(PGconn *, conn)

#define FOR_EACH_PARAM_OF_PQsendDescribePortal(param) \
param(PGconn *, conn)

#define FOR_EACH_PARAM_OF_PQsendClosePrepared(param) \
param(PGconn *, conn)

#define FOR_EACH_PARAM_OF_PQsendClosePortal(param) \
param(PGconn *, conn)

#define FOR_EACH_PARAM_OF_PQpipelineSync(param)

#define FOR_EACH_PARAM_OF_PQsendPipelineSync(param)

#define FOR_EACH_PARAM_OF_PQsetClientEncoding(param) \
param(PGconn *, conn)

Expand All @@ -225,11 +163,6 @@ typedef struct pg_cancel_conn PGcancelConn;
#define FOR_EACH_PARAM_OF_PQcancelStart(param)
#define FOR_EACH_PARAM_OF_PQcancelPoll(param)

#define FOR_EACH_PARAM_OF_PQencryptPasswordConn(param) \
param(PGconn *, conn) \
param(const char *, passwd) \
param(const char *, user)

#define FOR_EACH_PARAM_OF_PQcancel(param) \
param(PGcancel *, cancel) \
param(char *, errbuf)
Expand All @@ -243,35 +176,16 @@ typedef struct pg_cancel_conn PGcancelConn;
function(PQresetStart, GVL_TYPE_NONVOID, int, PGconn *, conn) \
function(PQresetPoll, GVL_TYPE_NONVOID, PostgresPollingStatusType, PGconn *, conn) \
function(PQping, GVL_TYPE_NONVOID, PGPing, const char *, conninfo) \
function(PQexec, GVL_TYPE_NONVOID, PGresult *, const char *, command) \
function(PQexecParams, GVL_TYPE_NONVOID, PGresult *, int, resultFormat) \
function(PQexecPrepared, GVL_TYPE_NONVOID, PGresult *, int, resultFormat) \
function(PQprepare, GVL_TYPE_NONVOID, PGresult *, const Oid *, paramTypes) \
function(PQdescribePrepared, GVL_TYPE_NONVOID, PGresult *, const char *, stmtName) \
function(PQdescribePortal, GVL_TYPE_NONVOID, PGresult *, const char *, portalName) \
function(PQclosePrepared, GVL_TYPE_NONVOID, PGresult *, const char *, stmtName) \
function(PQclosePortal, GVL_TYPE_NONVOID, PGresult *, const char *, portalName) \
function(PQgetResult, GVL_TYPE_NONVOID, PGresult *, PGconn *, conn) \
function(PQputCopyData, GVL_TYPE_NONVOID, int, int, nbytes) \
function(PQputCopyEnd, GVL_TYPE_NONVOID, int, const char *, errormsg) \
function(PQgetCopyData, GVL_TYPE_NONVOID, int, int, async) \
function(PQnotifies, GVL_TYPE_NONVOID, PGnotify *, PGconn *, conn) \
function(PQsendQuery, GVL_TYPE_NONVOID, int, const char *, query) \
function(PQsendQueryParams, GVL_TYPE_NONVOID, int, int, resultFormat) \
function(PQsendPrepare, GVL_TYPE_NONVOID, int, const Oid *, paramTypes) \
function(PQsendQueryPrepared, GVL_TYPE_NONVOID, int, int, resultFormat) \
function(PQsendDescribePrepared, GVL_TYPE_NONVOID, int, const char *, stmt) \
function(PQsendDescribePortal, GVL_TYPE_NONVOID, int, const char *, portal) \
function(PQsendClosePrepared, GVL_TYPE_NONVOID, int, const char *, stmt) \
function(PQsendClosePortal, GVL_TYPE_NONVOID, int, const char *, portal) \
function(PQpipelineSync, GVL_TYPE_NONVOID, int, PGconn *, conn) \
function(PQsendPipelineSync, GVL_TYPE_NONVOID, int, PGconn *, conn) \
function(PQsetClientEncoding, GVL_TYPE_NONVOID, int, const char *, encoding) \
function(PQisBusy, GVL_TYPE_NONVOID, int, PGconn *, conn) \
function(PQcancelBlocking, GVL_TYPE_NONVOID, int, PGcancelConn *, conn) \
function(PQcancelStart, GVL_TYPE_NONVOID, int, PGcancelConn *, conn) \
function(PQcancelPoll, GVL_TYPE_NONVOID, PostgresPollingStatusType, PGcancelConn *, conn) \
function(PQencryptPasswordConn, GVL_TYPE_NONVOID, char *, const char *, algorithm) \
function(PQcancel, GVL_TYPE_NONVOID, int, int, errbufsize);

FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_STUB_DECL );
Expand Down
2 changes: 2 additions & 0 deletions ext/pg.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ typedef long suseconds_t;

#define pg_gc_location(x) x = rb_gc_location(x)

extern int ruby_native_thread_p(void);

/* For compatibility with ruby < 3.0 */
#ifndef RUBY_TYPED_FROZEN_SHAREABLE
#define PG_RUBY_TYPED_FROZEN_SHAREABLE 0
Expand Down
Loading
Loading