Skip to content

Commit 31a8df0

Browse files
authored
Clarify thread-safety of SharedFlow methods in docs (#2399)
* Clarify thread-safety of SharedFlow methods in docs * Override MutableSharedFlow.emit to attach a more appropriate docs than the one inherited from FlowCollector. * Clarify thread-safety of all the MutableSharedFlow & MutableState "mutating" methods. The latter is needed, because Flows, in general, are sequential, but shared flows provide all the necessarily synchronization themselves, so, to avoid confusion it makes sense to additionally mention thread-safety of shared flows in all the relevant mutating functions.
1 parent 4fe809f commit 31a8df0

File tree

3 files changed

+24
-0
lines changed

3 files changed

+24
-0
lines changed

kotlinx-coroutines-core/api/kotlinx-coroutines-core.api

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,6 +1064,7 @@ public final class kotlinx/coroutines/flow/LintKt {
10641064
}
10651065

10661066
public abstract interface class kotlinx/coroutines/flow/MutableSharedFlow : kotlinx/coroutines/flow/FlowCollector, kotlinx/coroutines/flow/SharedFlow {
1067+
public abstract fun emit (Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
10671068
public abstract fun getSubscriptionCount ()Lkotlinx/coroutines/flow/StateFlow;
10681069
public abstract fun resetReplayCache ()V
10691070
public abstract fun tryEmit (Ljava/lang/Object;)Z

kotlinx-coroutines-core/common/src/flow/SharedFlow.kt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,17 @@ public interface SharedFlow<out T> : Flow<T> {
147147
* Use the `MutableSharedFlow(...)` constructor function to create an implementation.
148148
*/
149149
public interface MutableSharedFlow<T> : SharedFlow<T>, FlowCollector<T> {
150+
/**
151+
* Emits a [value] to this shared flow, suspending on buffer overflow if the shared flow was created
152+
* with the default [BufferOverflow.SUSPEND] strategy.
153+
*
154+
* See [tryEmit] for a non-suspending variant of this function.
155+
*
156+
* This method is **thread-safe** and can be safely invoked from concurrent coroutines without
157+
* external synchronization.
158+
*/
159+
override suspend fun emit(value: T)
160+
150161
/**
151162
* Tries to emit a [value] to this shared flow without suspending. It returns `true` if the value was
152163
* emitted successfully. When this function returns `false`, it means that the call to a plain [emit]
@@ -155,6 +166,9 @@ public interface MutableSharedFlow<T> : SharedFlow<T>, FlowCollector<T> {
155166
* A shared flow configured with a [BufferOverflow] strategy other than [SUSPEND][BufferOverflow.SUSPEND]
156167
* (either [DROP_OLDEST][BufferOverflow.DROP_OLDEST] or [DROP_LATEST][BufferOverflow.DROP_LATEST]) never
157168
* suspends on [emit], and thus `tryEmit` to such a shared flow always returns `true`.
169+
*
170+
* This method is **thread-safe** and can be safely invoked from concurrent coroutines without
171+
* external synchronization.
158172
*/
159173
public fun tryEmit(value: T): Boolean
160174

@@ -190,6 +204,9 @@ public interface MutableSharedFlow<T> : SharedFlow<T>, FlowCollector<T> {
190204
* supported, and throws an [UnsupportedOperationException]. To reset a [MutableStateFlow]
191205
* to an initial value, just update its [value][MutableStateFlow.value].
192206
*
207+
* This method is **thread-safe** and can be safely invoked from concurrent coroutines without
208+
* external synchronization.
209+
*
193210
* **Note: This is an experimental api.** This function may be removed or renamed in the future.
194211
*/
195212
@ExperimentalCoroutinesApi

kotlinx-coroutines-core/common/src/flow/StateFlow.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,9 @@ public interface MutableStateFlow<T> : StateFlow<T>, MutableSharedFlow<T> {
160160
* The current value of this state flow.
161161
*
162162
* Setting a value that is [equal][Any.equals] to the previous one does nothing.
163+
*
164+
* This property is **thread-safe** and can be safely updated from concurrent coroutines without
165+
* external synchronization.
163166
*/
164167
public override var value: T
165168

@@ -170,6 +173,9 @@ public interface MutableStateFlow<T> : StateFlow<T>, MutableSharedFlow<T> {
170173
* This function use a regular comparison using [Any.equals]. If both [expect] and [update] are equal to the
171174
* current [value], this function returns `true`, but it does not actually change the reference that is
172175
* stored in the [value].
176+
*
177+
* This method is **thread-safe** and can be safely invoked from concurrent coroutines without
178+
* external synchronization.
173179
*/
174180
public fun compareAndSet(expect: T, update: T): Boolean
175181
}

0 commit comments

Comments
 (0)