|
10 | 10 | #include <erl_nif.h> |
11 | 11 | #include <sqlite3.h> |
12 | 12 |
|
13 | | -// --------------------------------------------------------------------------- |
14 | 13 | // Platform timed-wait abstraction |
15 | 14 | // |
16 | | -// We need pthread_cond_timedwait / SleepConditionVariableCS because OTP's |
17 | | -// enif_cond does not expose a timed wait (deliberate omission due to clock |
18 | | -// jump safety concerns in telecom). BEAM has exactly two threading backends |
19 | | -// (pthreads and Win32), so #ifdef _WIN32 covers 100% of supported platforms. |
20 | | -// --------------------------------------------------------------------------- |
| 15 | +// OTP doesn't provide enif_cond_timedwait, so we wrap pthread_cond_timedwait |
| 16 | +// (POSIX) and SleepConditionVariableCS (Windows). BEAM has two threading |
| 17 | +// backends (pthreads and Win32), so #ifdef _WIN32 covers all platforms. |
21 | 18 |
|
22 | 19 | #ifdef _WIN32 |
23 | 20 | #include <windows.h> |
@@ -63,8 +60,7 @@ typedef struct { |
63 | 60 | static void tw_init(timed_wait_t* tw) |
64 | 61 | { |
65 | 62 | pthread_mutex_init(&tw->mtx, NULL); |
66 | | - // Use CLOCK_REALTIME (the default) because macOS doesn't support |
67 | | - // pthread_condattr_setclock(CLOCK_MONOTONIC). |
| 63 | + // CLOCK_REALTIME: macOS doesn't support CLOCK_MONOTONIC for condvars |
68 | 64 | pthread_cond_init(&tw->cond, NULL); |
69 | 65 | } |
70 | 66 |
|
@@ -146,11 +142,11 @@ typedef struct connection |
146 | 142 | int authorizer_deny[AUTHORIZER_DENY_SIZE]; |
147 | 143 |
|
148 | 144 | // Custom busy handler state |
149 | | - timed_wait_t cancel_tw; // condvar for cancellable busy waits |
150 | | - volatile int cancelled; // 1 = cancel requested (volatile for MSVC compat) |
151 | | - int busy_timeout_ms; // total busy timeout in milliseconds |
152 | | - ErlNifEnv* callback_env; // env for enif_is_process_alive checks |
153 | | - ErlNifPid caller_pid; // pid of the process that started the current op |
| 145 | + timed_wait_t cancel_tw; |
| 146 | + volatile int cancelled; // volatile for MSVC compat |
| 147 | + int busy_timeout_ms; |
| 148 | + ErlNifEnv* callback_env; // for enif_is_process_alive |
| 149 | + ErlNifPid caller_pid; |
154 | 150 | } connection_t; |
155 | 151 |
|
156 | 152 | typedef struct statement |
@@ -1966,11 +1962,8 @@ exqlite_interrupt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) |
1966 | 1962 | } |
1967 | 1963 |
|
1968 | 1964 | /// |
1969 | | -/// Set the busy timeout without destroying the custom busy handler. |
1970 | | -/// |
1971 | | -/// Unlike PRAGMA busy_timeout (which internally calls sqlite3_busy_timeout() |
1972 | | -/// and replaces any custom handler), this NIF only updates the timeout value |
1973 | | -/// that our custom handler reads. |
| 1965 | +/// Set busy timeout without destroying the custom handler. |
| 1966 | +/// (PRAGMA busy_timeout calls sqlite3_busy_timeout() which replaces handlers) |
1974 | 1967 | /// |
1975 | 1968 | ERL_NIF_TERM |
1976 | 1969 | exqlite_set_busy_timeout(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) |
@@ -2000,11 +1993,8 @@ exqlite_set_busy_timeout(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) |
2000 | 1993 | return am_ok; |
2001 | 1994 | } |
2002 | 1995 |
|
2003 | | -/// |
2004 | | -/// Cancel a running query: wake the busy handler and interrupt VDBE execution. |
2005 | | -/// |
2006 | | -/// This is a superset of interrupt/1 — it sets the cancel flag, signals the |
2007 | | -/// condvar to wake any busy handler sleep, AND calls sqlite3_interrupt(). |
| 1996 | +/// Cancel: wake busy handler + interrupt VDBE. |
| 1997 | +/// Superset of interrupt/1: sets flag, signals condvar, calls sqlite3_interrupt(). |
2008 | 1998 | /// |
2009 | 1999 | ERL_NIF_TERM |
2010 | 2000 | exqlite_cancel(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) |
|
0 commit comments