@@ -21,6 +21,7 @@ package sqlite3
21
21
#cgo CFLAGS: -DSQLITE_DISABLE_INTRINSIC
22
22
#cgo CFLAGS: -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1
23
23
#cgo CFLAGS: -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT
24
+ #cgo CFLAGS: -DSQLITE_ENABLE_UNLOCK_NOTIFY
24
25
#cgo CFLAGS: -Wno-deprecated-declarations
25
26
#cgo linux,!android CFLAGS: -DHAVE_PREAD64=1 -DHAVE_PWRITE64=1
26
27
#ifndef USE_LIBSQLITE3
@@ -88,6 +89,100 @@ _sqlite3_step(sqlite3_stmt* stmt, long long* rowid, long long* changes)
88
89
return rv;
89
90
}
90
91
92
+ #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
93
+ static int
94
+ sqlite3_step_internal(sqlite3_stmt *stmt)
95
+ {
96
+ extern int unlock_notify_wait(sqlite3 *db);
97
+ int rv;
98
+ sqlite3* db = sqlite3_db_handle(stmt);
99
+
100
+ for (;;) {
101
+ rv = sqlite3_step(stmt);
102
+ if (rv!=SQLITE_LOCKED) {
103
+ break;
104
+ }
105
+ if (sqlite3_extended_errcode(db)!=SQLITE_LOCKED_SHAREDCACHE) {
106
+ break;
107
+ }
108
+ rv = unlock_notify_wait(db);
109
+ if (rv != SQLITE_OK) {
110
+ break;
111
+ }
112
+ sqlite3_reset(stmt);
113
+ }
114
+
115
+ return rv;
116
+ }
117
+
118
+ static int
119
+ _sqlite3_step_internal(sqlite3_stmt* stmt, long long* rowid, long long* changes)
120
+ {
121
+ extern int unlock_notify_wait(sqlite3 *db);
122
+ int rv;
123
+ sqlite3* db = sqlite3_db_handle(stmt);
124
+
125
+ for (;;) {
126
+ rv = _sqlite3_step(stmt, rowid, changes);
127
+ if (rv!=SQLITE_LOCKED) {
128
+ break;
129
+ }
130
+ if (sqlite3_extended_errcode(db)!=SQLITE_LOCKED_SHAREDCACHE) {
131
+ break;
132
+ }
133
+ rv = unlock_notify_wait(db);
134
+ if (rv != SQLITE_OK) {
135
+ break;
136
+ }
137
+ sqlite3_reset(stmt);
138
+ }
139
+
140
+ return rv;
141
+ }
142
+
143
+ static int
144
+ sqlite3_prepare_v2_internal(sqlite3 *db, const char *zSql, int nBytes, sqlite3_stmt **ppStmt, const char **pzTail)
145
+ {
146
+ extern int unlock_notify_wait(sqlite3 *db);
147
+ int rv;
148
+
149
+ for (;;) {
150
+ rv = sqlite3_prepare_v2(db, zSql, nBytes, ppStmt, pzTail);
151
+ if (rv==SQLITE_OK) {
152
+ break;
153
+ } else if (rv==SQLITE_LOCKED) {
154
+ rv = unlock_notify_wait(db);
155
+ if (rv != SQLITE_OK) {
156
+ break;
157
+ }
158
+ } else {
159
+ break;
160
+ }
161
+ }
162
+
163
+ return rv;
164
+ }
165
+ #else
166
+
167
+ static int
168
+ sqlite3_step_internal(sqlite3_stmt *stmt)
169
+ {
170
+ return sqlite3_step(stmt);
171
+ }
172
+
173
+ static int
174
+ _sqlite3_step_internal(sqlite3_stmt* stmt, long long* rowid, long long* changes)
175
+ {
176
+ return _sqlite3_step(stmt, rowid, changes);
177
+ }
178
+
179
+ static int
180
+ sqlite3_prepare_v2_internal(sqlite3 *db, const char *zSql, int nBytes, sqlite3_stmt **ppStmt, const char **pzTail)
181
+ {
182
+ return sqlite3_prepare_v2(db, zSql, nBytes, ppStmt, pzTail);
183
+ }
184
+ #endif
185
+
91
186
void _sqlite3_result_text(sqlite3_context* ctx, const char* s) {
92
187
sqlite3_result_text(ctx, s, -1, &free);
93
188
}
@@ -1637,7 +1732,7 @@ func (c *SQLiteConn) prepare(ctx context.Context, query string) (driver.Stmt, er
1637
1732
defer C .free (unsafe .Pointer (pquery ))
1638
1733
var s * C.sqlite3_stmt
1639
1734
var tail * C.char
1640
- rv := C .sqlite3_prepare_v2 (c .db , pquery , - 1 , & s , & tail )
1735
+ rv := C .sqlite3_prepare_v2_internal (c .db , pquery , - 1 , & s , & tail )
1641
1736
if rv != C .SQLITE_OK {
1642
1737
return nil , c .lastError ()
1643
1738
}
@@ -1871,7 +1966,7 @@ func (s *SQLiteStmt) exec(ctx context.Context, args []namedValue) (driver.Result
1871
1966
}
1872
1967
1873
1968
var rowid , changes C.longlong
1874
- rv := C ._sqlite3_step (s .s , & rowid , & changes )
1969
+ rv := C ._sqlite3_step_internal (s .s , & rowid , & changes )
1875
1970
if rv != C .SQLITE_ROW && rv != C .SQLITE_OK && rv != C .SQLITE_DONE {
1876
1971
err := s .c .lastError ()
1877
1972
C .sqlite3_reset (s .s )
@@ -1943,7 +2038,7 @@ func (rc *SQLiteRows) Next(dest []driver.Value) error {
1943
2038
if rc .s .closed {
1944
2039
return io .EOF
1945
2040
}
1946
- rv := C .sqlite3_step (rc .s .s )
2041
+ rv := C .sqlite3_step_internal (rc .s .s )
1947
2042
if rv == C .SQLITE_DONE {
1948
2043
return io .EOF
1949
2044
}
0 commit comments