SQLite.swift
SQLite.swift copied to clipboard
Thread Safe?
Apologies if I missed it, but I looked through the docs and I haven't seen anything mention whether or not SQLite.swift is thread safe.
I'm seeing some random EXC_BAD_ACCESS crashing that pops up inside of SQLite.swift when calling the libsqlite functions and I'm trying to determine if there's a leak or if it's related to using multiple threads to access the DB potentially concurrently.
There's a "Note on Thread Safety" here:
https://github.com/stephencelis/SQLite.swift/blob/c9d3082d1f5ddc2e55a792a8eb1a677b8a1b15f5/Documentation/Index.md#a-note-on-thread-safety
Do you have more information related to the crash you're seeing?
I'm also interested in this. What exactly does "Every database" mean? Every Connection?
@stephencelis Next time one pops up I'll forward it along, but from memory EXC_BAD_ACCESS is triggering in Statement.columnNames
and Statement.step()
when calling the respective libsqlite functions.
All crashes have come from operations submitted to an NSOperationQueue where there's a bunch of simultaneous reading and write transactions. This is part of an overall sync between the local DB and a sizable remote data source that triggers ~hourly, so it's fairly intensive on the DB and I wouldn't be surprised if I'm tripping some edge cases here.
I'm also interested in this. What exactly does "Every database" mean? Every Connection?
Yep, I'll update the docs to be clearer.
Next time one pops up I'll forward it along, but from memory EXC_BAD_ACCESS is triggering in Statement.columnNames and Statement.step() when calling the respective libsqlite functions.
The step
function is dispatched to a queue, but columnNames
is not. I hadn't thought that would be a problem, but if you internally use the sync
helper (on Connection
), I wonder if the problem will go away.
Just ran into this again, but this time it was in filter:
malloc: *** error for object 0x7f7ff7ace1f8: incorrect checksum for freed object - object was probably modified after being freed. *** set a breakpoint in malloc_error_break to debug
Specifically the stack trace is pointing to this code in Expression.swift:
public init<U : ExpressionType>(_ expression: U) {
self.init(expression.template, expression.bindings)
}
The code on my end I'm using to make the call looks approximately like this:
if let id = object.someId, dateString = object.someDate {
self.operationQueue.addOperationWithBlock {
if let row = db.pluck(table.filter(idField == id).filter(dateField == dateString)) {
// ...
}
}
}
If this were Objective-C, I'd say this was probably my fault, I missed a retain somewhere, but if let
in Swift should handle that.
I'm still not close to ruling out it's something I'm doing, but it does seem to be related to threading.
@shnhrrsn Note that PR #290 adds more error trapping, though still not for the pluck
method (being discussed in #305).
If you replace db.pluck
with db.prepare
and a limit 1
restriction, you'll essentially have the same thing and can trap it... Could be worth a try (if you're still using SQLite.swift
that is...?)