Skip to content

Commit 6647411

Browse files
committed
Native (All): Fixes and new SharedImmutable annotations
Testing revealed that accessing even immutable fields concurrently is not supported out-of-the-box and instead crashes the Kotlin Native runtime.
1 parent 08bb887 commit 6647411

File tree

7 files changed

+29
-22
lines changed

7 files changed

+29
-22
lines changed

core/commonMain/src/DayOfWeek.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
package kotlinx.datetime
77

8+
import kotlin.native.concurrent.*
9+
810
public expect enum class DayOfWeek {
911
MONDAY,
1012
TUESDAY,
@@ -17,6 +19,7 @@ public expect enum class DayOfWeek {
1719

1820
public val DayOfWeek.number: Int get() = ordinal + 1
1921

22+
@SharedImmutable
2023
private val allDaysOfWeek = DayOfWeek.values().asList()
2124
public fun DayOfWeek(number: Int): DayOfWeek {
2225
require(number in 1..7)

core/commonMain/src/Month.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
package kotlinx.datetime
77

8+
import kotlin.native.concurrent.*
9+
810
public expect enum class Month {
911
JANUARY,
1012
FEBRUARY,
@@ -24,7 +26,9 @@ public expect enum class Month {
2426

2527
public val Month.number: Int get() = ordinal + 1
2628

29+
@SharedImmutable
2730
private val allMonths = Month.values().asList()
31+
2832
public fun Month(number: Int): Month {
2933
require(number in 1..12)
3034
return allMonths[number - 1]

core/nativeMain/cinterop/cpp/cdate.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@ static char * timezone_name(const T& zone)
3232

3333
static const time_zone *zone_by_id(TZID id)
3434
{
35+
/* The `date` library provides a linked list of `tzdb` objects. `get_tzdb()`
36+
always returns the head of that list. For now, the list never changes:
37+
a call to `reload_tzdb()` would be required to load the updated version
38+
of the timezone database. We never do this because for now (with use of
39+
`date`) this operation is not even present for the configuration that
40+
uses the system timezone database. If we move to C++20 support for this,
41+
it may be feasible to call `reload_tzdb()` and construct a more elaborate
42+
ID scheme. */
3543
auto& tzdb = get_tzdb();
3644
try {
3745
return &tzdb.zones.at(id);

core/nativeMain/src/Instant.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ public actual enum class DayOfWeek {
2525
}
2626

2727
// org.threeten.bp.format.DateTimeFormatterBuilder.InstantPrinterParser#parse
28-
private val instantParser: Parser<Instant> =
29-
localDateParser
28+
private val instantParser: Parser<Instant>
29+
get() = localDateParser
3030
.chainIgnoring(concreteCharParser('T').or(concreteCharParser('t')))
3131
.chain(intParser(2, 2)) // hour
3232
.chainIgnoring(concreteCharParser(':'))

core/nativeMain/src/LocalDate.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public actual class LocalDate actual constructor(actual val year: Int, actual va
4242

4343
// org.threeten.bp.LocalDate#toEpochDay
4444
internal fun ofEpochDay(epochDay: Long): LocalDate {
45-
require(epochDay in -365243219162L..365241780471L)
45+
require(epochDay >= -365243219162L && epochDay <= 365241780471L)
4646
var zeroDay: Long = epochDay + DAYS_0000_TO_1970
4747
// find the march-based year
4848
zeroDay -= 60 // adjust to 0000-03-01 so leap day is at end of four year cycle

core/nativeMain/src/Parser.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ internal fun <T, S> Parser<T>.chainIgnoring(other: Parser<S>): Parser<T> =
2626
internal fun <T, S> Parser<T>.chainSkipping(other: Parser<S>): Parser<S> =
2727
chain(other).map { (_, s) -> s }
2828

29+
@SharedImmutable
2930
internal val eofParser: Parser<Unit> = { str, pos ->
3031
if (str.length > pos) {
3132
throw ParseException("extraneous input", pos)

core/nativeMain/src/TimeZone.kt

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,28 +18,18 @@ public actual open class TimeZone internal constructor(val tzid: TZID, actual va
1818

1919
private val asciiName = id.cstr
2020

21-
@ThreadLocal
2221
actual companion object {
2322

24-
private var systemTimeZoneCached: TimeZone? = null
25-
26-
actual val SYSTEM: TimeZone
27-
get() {
28-
val cached = systemTimeZoneCached
29-
if (cached != null) {
30-
return cached
31-
}
32-
val systemTimeZone = memScoped {
33-
val tzid = alloc<TZIDVar>()
34-
val string = get_system_timezone(tzid.ptr) ?: throw RuntimeException("Failed to get the system timezone.")
35-
val kotlinString = string.toKString()
36-
free(string)
37-
TimeZone(tzid.value, kotlinString)
38-
}
39-
systemTimeZoneCached = systemTimeZone
40-
return systemTimeZone
41-
}
23+
@SharedImmutable
24+
actual val SYSTEM: TimeZone = memScoped {
25+
val tzid = alloc<TZIDVar>()
26+
val string = get_system_timezone(tzid.ptr) ?: throw RuntimeException("Failed to get the system timezone.")
27+
val kotlinString = string.toKString()
28+
free(string)
29+
TimeZone(tzid.value, kotlinString)
30+
}
4231

32+
@SharedImmutable
4333
actual val UTC: TimeZone = ZoneOffset.UTC
4434

4535
// org.threeten.bp.ZoneId#of(java.lang.String)
@@ -140,6 +130,7 @@ public actual class ZoneOffset internal constructor(actual val totalSeconds: Int
140130

141131
companion object {
142132
// org.threeten.bp.ZoneOffset#UTC
133+
@SharedImmutable
143134
val UTC = ZoneOffset(0, "Z")
144135

145136
// org.threeten.bp.ZoneOffset#of

0 commit comments

Comments
 (0)