Skip to content

Commit 66b82b0

Browse files
committed
Use vfs for exclusivity
vfs seems to be a more reliable handling of exclusive mode.
1 parent 68f46d5 commit 66b82b0

File tree

3 files changed

+25
-14
lines changed

3 files changed

+25
-14
lines changed

SQLite/Core/Connection.swift

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -268,9 +268,9 @@ public final class DBConnection : Connection, Equatable {
268268
/// Default: `false`.
269269
///
270270
/// - Returns: A new database connection.
271-
public convenience init(_ location: Location = .InMemory, readonly: Bool = false) throws {
271+
public convenience init(_ location: Location = .InMemory, readonly: Bool = false, vfsName: String? = nil) throws {
272272
let flags = readonly ? SQLITE_OPEN_READONLY : SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE
273-
try self.init(location, flags: flags, dispatcher: ReentrantDispatcher("SQLite.Connection"))
273+
try self.init(location, flags: flags, dispatcher: ReentrantDispatcher("SQLite.Connection"), vfsName: vfsName)
274274
}
275275

276276
/// Initializes a new SQLite connection.
@@ -285,9 +285,14 @@ public final class DBConnection : Connection, Equatable {
285285
/// - dispatcher: Dispatcher synchronization blocks
286286
///
287287
/// - Returns: A new database connection.
288-
public init(_ location: Location, flags: Int32, dispatcher: Dispatcher) throws {
288+
public init(_ location: Location, flags: Int32, dispatcher: Dispatcher, vfsName: String? = nil) throws {
289289
self.dispatcher = dispatcher
290-
try check(sqlite3_open_v2(location.description, &_handle, flags, nil))
290+
if let vfsName = vfsName {
291+
try check(sqlite3_open_v2(location.description, &_handle, flags, vfsName))
292+
}
293+
else {
294+
try check(sqlite3_open_v2(location.description, &_handle, flags, nil))
295+
}
291296
try check(sqlite3_extended_result_codes(handle, 1))
292297
}
293298

SQLite/Core/ConnectionPool.swift

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
import Foundation
2626

2727

28+
private let vfsName = "unix-excl"
29+
30+
2831
/// Connection pool delegate
2932
public protocol ConnectionPoolDelegate {
3033

@@ -44,15 +47,13 @@ public final class ConnectionPool {
4447
private var unavailableReadConnections = [DBConnection]()
4548
private let lockQueue : dispatch_queue_t
4649
private var writeConnection : DBConnection!
47-
private let writeQueue : dispatch_queue_t
4850

4951
public var delegate : ConnectionPoolDelegate?
5052

5153
public init(_ location: DBConnection.Location) throws {
5254
self.location = location
5355
self.lockQueue = dispatch_queue_create("SQLite.ConnectionPool.Lock", DISPATCH_QUEUE_SERIAL)
54-
self.writeQueue = dispatch_queue_create("SQLite.ConnectionPool.Write", DISPATCH_QUEUE_SERIAL)
55-
try writable.execute("PRAGMA locking_mode = EXCLUSIVE; PRAGMA journal_mode = WAL;")
56+
try writable.execute("PRAGMA journal_mode = WAL;")
5657
}
5758

5859
public var totalReadableConnectionCount : Int {
@@ -114,12 +115,16 @@ public final class ConnectionPool {
114115
// Acquires a read/write connection to the database
115116
public var writable : DBConnection {
116117

117-
118118
var writeConnectionInit = dispatch_once_t()
119119
dispatch_once(&writeConnectionInit) {
120-
let flags = SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE | SQLITE_OPEN_WAL
121-
self.writeConnection = try! DBConnection(self.location, flags: flags, dispatcher: ReentrantDispatcher("SQLite.WriteConnection"))
120+
121+
let flags = SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE | SQLITE_OPEN_WAL | SQLITE_OPEN_NOMUTEX
122+
self.writeConnection = try! DBConnection(self.location, flags: flags, dispatcher: ReentrantDispatcher("SQLite.ConnectionPool.Write"), vfsName: vfsName)
122123
self.writeConnection.busyTimeout = 2
124+
125+
if let delegate = self.delegate {
126+
delegate.pool(self, didAddConnection: self.writeConnection)
127+
}
123128
}
124129

125130
return writeConnection
@@ -141,8 +146,9 @@ public final class ConnectionPool {
141146
}
142147
else if self.delegate?.poolShouldAddConnection(self) ?? true {
143148

144-
let flags = SQLITE_OPEN_READONLY | SQLITE_OPEN_WAL
145-
connection = try! DBConnection(self.location, flags: flags, dispatcher: ImmediateDispatcher())
149+
let flags = SQLITE_OPEN_READONLY | SQLITE_OPEN_WAL | SQLITE_OPEN_NOMUTEX
150+
151+
connection = try! DBConnection(self.location, flags: flags, dispatcher: ImmediateDispatcher(), vfsName: vfsName)
146152
connection.busyTimeout = 2
147153

148154
self.delegate?.pool(self, didAddConnection: connection)

SQLiteTests/ConnectionPoolTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class ConnectionPoolTests : SQLiteTestCase {
3434

3535
let conn = pool.readable
3636

37-
let stmt = conn.prepare("SELECT name FROM test WHERE id = ?")
37+
let stmt = try! conn.prepare("SELECT name FROM test WHERE id = ?")
3838
var curr = stmt.scalar(x) as! String
3939
while !quit {
4040

@@ -65,7 +65,7 @@ class ConnectionPoolTests : SQLiteTestCase {
6565
XCTFail((error as? CustomStringConvertible)?.description ?? "Unknown")
6666
}
6767

68-
usleep(15000)
68+
usleep(1500)
6969
}
7070

7171
quit = true

0 commit comments

Comments
 (0)