Skip to content

Kpg/memory model changes #66

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 26, 2022
Merged
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
5 changes: 4 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ jobs:
build:
strategy:
matrix:
os: [ macOS-latest, windows-latest, ubuntu-18.04 ]
os: [ macOS-latest, ubuntu-18.04 ]
# os: [ macOS-latest, windows-latest, ubuntu-18.04 ]
runs-on: ${{matrix.os}}
steps:
- name: Checkout the repo
Expand Down Expand Up @@ -47,5 +48,7 @@ jobs:
- name: Build
run: ./gradlew build --no-daemon --stacktrace

- name: Build New Memory Model
run: ./gradlew build --no-daemon --stacktrace -Pkotlin.native.binary.memoryModel=experimental
env:
GRADLE_OPTS: -Dorg.gradle.configureondemand=true -Dkotlin.incremental=false -Dorg.gradle.jvmargs="-Xmx3g -XX:MaxPermSize=2048m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -XX:MaxMetaspaceSize=512m"
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
kotlin.code.style=official

GROUP=co.touchlab
VERSION_NAME=1.0.10
KOTLIN_VERSION=1.5.30
VERSION_NAME=1.0.11
KOTLIN_VERSION=1.6.20-RC2

kotlin.native.ignoreDisabledTargets=true

Expand Down
6 changes: 6 additions & 0 deletions sqliter-driver/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,12 @@ if(!HostManager.hostIsLinux) {
tasks.findByName("publishLinuxX64PublicationToMavenRepository")?.enabled = false
}

if(!HostManager.hostIsMingw) {
tasks.findByName("mingwX64Test")?.enabled = false
tasks.findByName("linkDebugTestMingwX64")?.enabled = false
tasks.findByName("publishMingwX64PublicationToMavenRepository")?.enabled = false
}

apply(from = "../gradle/gradle-mvn-mpp-push.gradle")

tasks.register("publishMac"){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ actual object DatabaseFileContext{
{
val prefix = file.getName() + "-mj"
val files = dir.listFiles(object: FileFilter {
override fun accept(candidate: File):Boolean {
return candidate.getName().startsWith(prefix)
override fun accept(pathname: File):Boolean {
return pathname.getName().startsWith(prefix)
}
})
if (files != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,38 +44,15 @@ internal actual class File(dirPath:String?=null, name:String){
* This field is initialized from the system property "file.separator".
* Later changes to that property will have no effect on this field or this class.
*/
var separatorChar: Char = '/'
val separatorChar: Char = '/'

/**
* The system-dependent string used to separate components in filenames ('/').
* See [.separatorChar].
*/
var separator: String = "/"
val separator: String = "/"

/**
* The system-dependent character used to separate components in search paths (':').
* This is used to split such things as the PATH environment variable and classpath
* system properties into lists of directories to be searched.
*
*
* This field is initialized from the system property "path.separator".
* Later changes to that property will have no effect on this field or this class.
*/
var pathSeparatorChar: Char = ':'

/**
* The system-dependent string used to separate components in search paths (":").
* See [.pathSeparatorChar].
*/
var pathSeparator: String = ":"

private var caseSensitive: Boolean = true

// separatorChar = System.getProperty("file.separator", "/").charAt(0);
// pathSeparatorChar = System.getProperty("path.separator", ":").charAt(0);
// separator = String.valueOf(separatorChar);
// pathSeparator = String.valueOf(pathSeparatorChar);
// caseSensitive = isCaseSensitiveImpl();
private val caseSensitive: Boolean = true
}

/**
Expand Down Expand Up @@ -272,9 +249,7 @@ internal actual class File(dirPath:String?=null, name:String){
* @return the number of bytes in this file.
*/
fun length(): Long{
val attrMap = defaultFileManager().attributesOfItemAtPath(path, null)
if(attrMap == null)
return 0
val attrMap = defaultFileManager().attributesOfItemAtPath(path, null) ?: return 0
return attrMap[NSFileSize] as Long
}

Expand All @@ -289,20 +264,13 @@ internal actual class File(dirPath:String?=null, name:String){
*
* @return an array of strings with file names or `null`.
*/
fun list(): Array<String>? {
private fun list(): Array<String> {
return listImpl(path)
}

private fun listImpl(path: String): Array<String>?{
private fun listImpl(path: String): Array<String> {
val pathList = defaultFileManager().contentsOfDirectoryAtPath(path, null) as List<*>
if(pathList == null)
{
return null
}
else {
val pathArray = Array<String>(pathList.size, { i -> pathList[i] as String })
return pathArray
}
return Array(pathList.size) { i -> pathList[i] as String }
}

/**
Expand All @@ -322,12 +290,12 @@ internal actual class File(dirPath:String?=null, name:String){
*/
fun list(filter: FilenameFilter?): Array<String>? {
val filenames = list()
if (filter == null || filenames == null) {
if (filter == null) {
return filenames
}
val result = ArrayList<String>(filenames.size)
for (filename in filenames) {
if (filter!!.accept(this, filename)) {
if (filter.accept(this, filename)) {
result.add(filename)
}
}
Expand Down Expand Up @@ -386,7 +354,7 @@ internal actual class File(dirPath:String?=null, name:String){
}
val result = ArrayList<File>(files.size)
for (file in files) {
if (filter!!.accept(file)) {
if (filter.accept(file)) {
result.add(file)
}
}
Expand All @@ -404,10 +372,8 @@ internal actual class File(dirPath:String?=null, name:String){
return null
}
val count = filenames.size
val result = arrayOfNulls<File>(count)

val files = Array<File>(count, {i -> File(this, filenames[i])})
return files
return Array(count) { i -> File(this, filenames[i]) }
}

/**
Expand Down Expand Up @@ -448,10 +414,6 @@ internal actual class File(dirPath:String?=null, name:String){
* `false` on failure or if the directory already existed.
*/
fun mkdirs(): Boolean {
return mkdirs(false)
}

private fun mkdirs(resultIfExists: Boolean): Boolean {
/* If the terminal directory already exists, answer false */
if (exists()) {
return false
Expand All @@ -470,11 +432,9 @@ internal actual class File(dirPath:String?=null, name:String){
return defaultFileManager().createFileAtPath(path, null, null)
}

private fun getFileType(path:String):NSFileAttributeType?{
val attrMap = defaultFileManager().attributesOfItemAtPath(path, null)
if(attrMap == null)
return null
return attrMap[NSFileType] as NSFileAttributeType?
private fun getFileType(path:String):NSFileAttributeType{
val attrMap = defaultFileManager().attributesOfItemAtPath(path, null) ?: return null
return attrMap[NSFileType] as NSFileAttributeType
}

fun isDirectory(): Boolean{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package co.touchlab.sqliter.concurrency

import co.touchlab.sqliter.util.maybeFreeze
import kotlinx.cinterop.Arena
import kotlinx.cinterop.alloc
import kotlinx.cinterop.ptr
import platform.posix.*
import kotlin.native.concurrent.freeze

/**
* A simple lock.
Expand All @@ -19,7 +19,7 @@ actual class Lock actual constructor() {
pthread_mutexattr_init(attr.ptr)
pthread_mutexattr_settype(attr.ptr, PTHREAD_MUTEX_RECURSIVE.toInt())
pthread_mutex_init(mutex.ptr, attr.ptr)
freeze()
maybeFreeze()
}

actual fun lock() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package co.touchlab.sqliter.concurrency

import co.touchlab.sqliter.util.maybeFreeze
import kotlinx.cinterop.Arena
import kotlinx.cinterop.alloc
import kotlinx.cinterop.ptr
Expand All @@ -14,7 +15,6 @@ import platform.posix.pthread_mutexattr_destroy
import platform.posix.pthread_mutexattr_init
import platform.posix.pthread_mutexattr_settype
import platform.posix.pthread_mutexattr_tVar
import kotlin.native.concurrent.freeze

/**
* A simple lock.
Expand All @@ -29,7 +29,7 @@ actual class Lock actual constructor() {
pthread_mutexattr_init(attr.ptr)
pthread_mutexattr_settype(attr.ptr, PTHREAD_MUTEX_RECURSIVE.toInt())
pthread_mutex_init(mutex.ptr, attr.ptr)
freeze()
maybeFreeze()
}

actual fun lock() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package co.touchlab.sqliter.concurrency

import co.touchlab.sqliter.util.maybeFreeze
import kotlinx.cinterop.Arena
import kotlinx.cinterop.alloc
import kotlinx.cinterop.ptr
Expand All @@ -14,7 +15,6 @@ import platform.posix.pthread_mutexattr_destroy
import platform.posix.pthread_mutexattr_init
import platform.posix.pthread_mutexattr_settype
import platform.posix.pthread_mutexattr_tVar
import kotlin.native.concurrent.freeze

/**
* A simple lock.
Expand All @@ -29,7 +29,7 @@ actual class Lock actual constructor() {
pthread_mutexattr_init(attr.ptr)
pthread_mutexattr_settype(attr.ptr, PTHREAD_MUTEX_RECURSIVE.toInt())
pthread_mutex_init(mutex.ptr, attr.ptr)
freeze()
maybeFreeze()
}

actual fun lock() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ enum class JournalMode {

companion object {
fun forString(s: String) =
if (s.toUpperCase().equals(WAL.name)) {
if (s.uppercase() == WAL.name) {
WAL
} else {
DELETE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package co.touchlab.sqliter

interface DatabaseConnection {
fun rawExecSql(sql: String)
fun createStatement(sql: String): Statement
fun beginTransaction()
fun setTransactionSuccessful()
Expand Down Expand Up @@ -98,7 +99,7 @@ val DatabaseConnection.journalMode: JournalMode

fun DatabaseConnection.updateJournalMode(value: JournalMode): JournalMode {
return if (journalMode != value) {
JournalMode.forString(stringForQuery("PRAGMA journal_mode=${value.name}").toUpperCase())
JournalMode.forString(stringForQuery("PRAGMA journal_mode=${value.name}").uppercase())
} else {
value
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import co.touchlab.sqliter.Statement
class ConcurrentDatabaseConnection(private val delegateConnection:DatabaseConnection):DatabaseConnection{
private val accessLock = Lock()

override fun rawExecSql(sql: String) = accessLock.withLock { delegateConnection.rawExecSql(sql) }

override fun createStatement(sql: String): Statement = accessLock.withLock { ConcurrentStatement(delegateConnection.createStatement(sql)) }

override fun beginTransaction() = accessLock.withLock { delegateConnection.beginTransaction() }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import kotlin.native.concurrent.ensureNeverFrozen
class SingleThreadDatabaseConnection(delegateConnection: DatabaseConnection):DatabaseConnection by delegateConnection
{
init {
ensureNeverFrozen()
if (Platform.memoryModel == MemoryModel.STRICT)
ensureNeverFrozen()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ class SqliteDatabase(path:String, label:String, val logger: Logger, private val
}
}

fun rawExecSql(sqlString: String){
val err = sqlite3_exec(dbPointer, sqlString, null, null, null)
if (err != SQLITE_OK) {
throw sqlException(logger, config, "error rawExecSql: $sqlString", err)
}
}

fun close(){
logger.v { "close $config" }

Expand All @@ -53,6 +60,7 @@ enum class OpenFlags {
OPEN_READONLY
}

@Suppress("UNUSED_PARAMETER")
fun dbOpen(
path: String,
openFlags: List<OpenFlags>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ import co.touchlab.sqliter.*
import co.touchlab.sqliter.concurrency.Lock
import co.touchlab.sqliter.concurrency.withLock
import co.touchlab.sqliter.interop.SqliteDatabase
import co.touchlab.sqliter.util.maybeFreeze
import kotlin.native.concurrent.AtomicInt
import kotlin.native.concurrent.AtomicReference
import kotlin.native.concurrent.freeze

class NativeDatabaseConnection(
val dbManager: NativeDatabaseManager,
Expand All @@ -36,6 +36,10 @@ class NativeDatabaseConnection(

data class Transaction(val successful: Boolean)

override fun rawExecSql(sql: String) {
sqliteDatabase.rawExecSql(sql)
}

override fun createStatement(sql: String): Statement {
val statementPtr = sqliteDatabase.prepareStatement(sql)
val statement = NativeStatement(this, statementPtr, sql)
Expand All @@ -45,12 +49,12 @@ class NativeDatabaseConnection(

override fun beginTransaction() = transLock.withLock {
withStatement("BEGIN;") { execute() }
transaction.value = Transaction(false).freeze()
transaction.value = Transaction(false).maybeFreeze()
}

override fun setTransactionSuccessful() = transLock.withLock {
val trans = checkFailTransaction()
transaction.value = trans.copy(successful = true).freeze()
transaction.value = trans.copy(successful = true).maybeFreeze()
}

override fun endTransaction() = transLock.withLock {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ import co.touchlab.sqliter.concurrency.SingleThreadDatabaseConnection
import co.touchlab.sqliter.concurrency.withLock
import co.touchlab.sqliter.interop.OpenFlags
import co.touchlab.sqliter.interop.dbOpen
import co.touchlab.sqliter.util.maybeFreeze
import kotlin.native.concurrent.AtomicInt
import kotlin.native.concurrent.freeze

class NativeDatabaseManager(private val path:String,
override val configuration: DatabaseConfiguration
): DatabaseManager {
override fun createMultiThreadedConnection(): DatabaseConnection {
return ConcurrentDatabaseConnection(createConnection()).freeze()
return ConcurrentDatabaseConnection(createConnection()).maybeFreeze()
}

override fun createSingleThreadedConnection(): DatabaseConnection {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package co.touchlab.sqliter.util

import kotlin.native.concurrent.freeze

internal inline fun <T> T.maybeFreeze(): T = if (Platform.memoryModel == MemoryModel.STRICT) {
this.freeze()
} else {
this
}
Loading