Global state demo. (#1236)

This commit is contained in:
Nikolay Igotti
2018-01-16 18:31:50 +03:00
committed by GitHub
parent 0c3d5c52fc
commit 0f85696ffb
5 changed files with 94 additions and 0 deletions
+9
View File
@@ -0,0 +1,9 @@
# Shared global state
This example shows how one could implement global shared state using interop mechanisms.
To build use `../gradlew build`.
To run use `./build/konan/bin/<platform>/Globals.exe`.
+15
View File
@@ -0,0 +1,15 @@
apply plugin: 'konan'
konan.targets = ['macbook', 'linux', 'mingw']
konanArtifacts {
interop('global') {
defFile 'src/main/c_interop/global.def'
}
program('Globals') {
libraries {
artifact 'global'
}
}
}
@@ -0,0 +1,10 @@
package = global
---
typedef struct {
int x;
float f;
char* string;
} SharedData;
SharedData sharedData;
@@ -0,0 +1,59 @@
/*
* Copyright 2010-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import global.*
import kotlinx.cinterop.*
import platform.posix.*
fun Int.ensureUnixCallResult(op: String, predicate: (Int) -> Boolean = { x -> x >= 0} ): Int {
if (!predicate(this)) {
throw Error("$op: ${strerror(posix_errno())!!.toKString()}")
}
return this
}
fun dumpShared(prefix: String) =
println("$prefix: ${pthread_self().rawValue} x=${sharedData.x} f=${sharedData.f} s=${sharedData.string!!.toKString()}")
fun main(args: Array<String>) {
// Arena owning all native allocs.
val arena = Arena()
// Assign global data.
sharedData.x = 239
sharedData.f = 0.5f
sharedData.string = "Hello Kotlin!".cstr.getPointer(arena)
dumpShared("thread1")
// Start a new thread, that sees the variable.
// memScoped is needed to pass thread's local address to pthread_create().
memScoped {
val thread = alloc<pthread_tVar>()
pthread_create(thread.ptr, null, staticCFunction {
_ ->
initRuntimeIfNeeded()
dumpShared("thread2")
// Workaround for compiler issue.
null as COpaquePointer?
}, null).ensureUnixCallResult("pthread_create")
pthread_join(thread.value, null).ensureUnixCallResult("pthread_join")
}
// At this moment we do not need data stored in shared data, so clean up the data
// and free memory.
sharedData.string = null
arena.clear()
}
+1
View File
@@ -3,6 +3,7 @@
include ':calculator'
include ':csvparser'
include ':gitchurn'
include ':globalState'
include ':gtk'
include ':libcurl'
include ':nonBlockingEchoServer'