Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
M
Mirai
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
MyCard
Mirai
Commits
3859ce6d
Commit
3859ce6d
authored
Feb 23, 2020
by
Him188
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Concurrent event processing
parent
9a72a667
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
71 additions
and
41 deletions
+71
-41
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/internal/InternalEventListeners.kt
.../net.mamoe.mirai/event/internal/InternalEventListeners.kt
+20
-9
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/subscriber.kt
...src/commonMain/kotlin/net.mamoe.mirai/event/subscriber.kt
+7
-0
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/LockFreeLinkedList.kt
...onMain/kotlin/net.mamoe.mirai/utils/LockFreeLinkedList.kt
+44
-32
No files found.
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/internal/InternalEventListeners.kt
View file @
3859ce6d
...
@@ -10,6 +10,8 @@
...
@@ -10,6 +10,8 @@
package
net.mamoe.mirai.event.internal
package
net.mamoe.mirai.event.internal
import
kotlinx.coroutines.*
import
kotlinx.coroutines.*
import
kotlinx.coroutines.sync.Mutex
import
kotlinx.coroutines.sync.withLock
import
net.mamoe.mirai.event.Event
import
net.mamoe.mirai.event.Event
import
net.mamoe.mirai.event.EventDisabled
import
net.mamoe.mirai.event.EventDisabled
import
net.mamoe.mirai.event.Listener
import
net.mamoe.mirai.event.Listener
...
@@ -73,6 +75,9 @@ internal class Handler<in E : Event>
...
@@ -73,6 +75,9 @@ internal class Handler<in E : Event>
ListeningStatus
.
LISTENING
ListeningStatus
.
LISTENING
}
}
}
}
@MiraiInternalAPI
override
val
lock
:
Mutex
=
Mutex
()
}
}
/**
/**
...
@@ -138,23 +143,29 @@ internal object EventListenerManager {
...
@@ -138,23 +143,29 @@ internal object EventListenerManager {
// inline: NO extra Continuation
// inline: NO extra Continuation
@Suppress
(
"UNCHECKED_CAST"
)
@Suppress
(
"UNCHECKED_CAST"
)
internal
suspend
inline
fun
Event
.
broadcastInternal
()
{
internal
suspend
inline
fun
Event
.
broadcastInternal
()
=
coroutineScope
{
if
(
EventDisabled
)
return
if
(
EventDisabled
)
return
@
coroutineScope
EventLogger
.
info
{
"Event broadcast: $this"
}
EventLogger
.
info
{
"Event broadcast: $this"
}
val
listeners
=
this
::
class
.
listeners
()
val
listeners
=
this
@
broadcastInternal
::
class
.
listeners
()
callAndRemoveIfRequired
(
listeners
)
callAndRemoveIfRequired
(
this
@
broadcastInternal
,
listeners
)
listeners
.
supertypes
.
forEach
{
listeners
.
supertypes
.
forEach
{
callAndRemoveIfRequired
(
it
.
listeners
())
callAndRemoveIfRequired
(
this
@
broadcastInternal
,
it
.
listeners
())
}
}
}
}
private
suspend
inline
fun
<
E
:
Event
>
E
.
callAndRemoveIfRequired
(
listeners
:
EventListeners
<
E
>)
{
@UseExperimental
(
MiraiInternalAPI
::
class
)
private
fun
<
E
:
Event
>
CoroutineScope
.
callAndRemoveIfRequired
(
event
:
E
,
listeners
:
EventListeners
<
E
>)
{
// atomic foreach
// atomic foreach
listeners
.
forEach
{
listeners
.
forEachNode
{
node
->
if
(
it
.
onEvent
(
this
)
==
ListeningStatus
.
STOPPED
)
{
launch
{
listeners
.
remove
(
it
)
// atomic remove
val
listener
=
node
.
nodeValue
listener
.
lock
.
withLock
{
if
(!
node
.
isRemoved
()
&&
listener
.
onEvent
(
event
)
==
ListeningStatus
.
STOPPED
)
{
listeners
.
remove
(
listener
)
// atomic remove
}
}
}
}
}
}
}
}
\ No newline at end of file
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/subscriber.kt
View file @
3859ce6d
...
@@ -13,6 +13,7 @@ import kotlinx.coroutines.CompletableJob
...
@@ -13,6 +13,7 @@ import kotlinx.coroutines.CompletableJob
import
kotlinx.coroutines.CoroutineExceptionHandler
import
kotlinx.coroutines.CoroutineExceptionHandler
import
kotlinx.coroutines.CoroutineScope
import
kotlinx.coroutines.CoroutineScope
import
kotlinx.coroutines.GlobalScope
import
kotlinx.coroutines.GlobalScope
import
kotlinx.coroutines.sync.Mutex
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.event.events.BotEvent
import
net.mamoe.mirai.event.events.BotEvent
import
net.mamoe.mirai.event.internal.Handler
import
net.mamoe.mirai.event.internal.Handler
...
@@ -51,6 +52,12 @@ enum class ListeningStatus {
...
@@ -51,6 +52,12 @@ enum class ListeningStatus {
* 取消监听: [complete]
* 取消监听: [complete]
*/
*/
interface
Listener
<
in
E
:
Event
>
:
CompletableJob
{
interface
Listener
<
in
E
:
Event
>
:
CompletableJob
{
/**
* [onEvent] 的锁
*/
@MiraiInternalAPI
val
lock
:
Mutex
suspend
fun
onEvent
(
event
:
E
):
ListeningStatus
suspend
fun
onEvent
(
event
:
E
):
ListeningStatus
}
}
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/LockFreeLinkedList.kt
View file @
3859ce6d
...
@@ -132,7 +132,7 @@ open class LockFreeLinkedList<E> {
...
@@ -132,7 +132,7 @@ open class LockFreeLinkedList<E> {
addLastNode
(
element
.
asNode
(
tail
))
addLastNode
(
element
.
asNode
(
tail
))
}
}
private
fun
addLastNode
(
node
:
Node
<
E
>)
{
private
fun
addLastNode
(
node
:
LockFreeLinkedList
Node
<
E
>)
{
while
(
true
)
{
while
(
true
)
{
val
tail
=
head
.
iterateBeforeFirst
{
it
===
tail
}
// find the last node.
val
tail
=
head
.
iterateBeforeFirst
{
it
===
tail
}
// find the last node.
if
(
tail
.
nextNodeRef
.
compareAndSet
(
this
.
tail
,
node
))
{
// ensure the last node is the last node
if
(
tail
.
nextNodeRef
.
compareAndSet
(
this
.
tail
,
node
))
{
// ensure the last node is the last node
...
@@ -146,9 +146,9 @@ open class LockFreeLinkedList<E> {
...
@@ -146,9 +146,9 @@ open class LockFreeLinkedList<E> {
*/
*/
@Suppress
(
"DuplicatedCode"
)
@Suppress
(
"DuplicatedCode"
)
open
fun
addAll
(
iterable
:
Iterable
<
E
>)
{
open
fun
addAll
(
iterable
:
Iterable
<
E
>)
{
var
firstNode
:
Node
<
E
>?
=
null
var
firstNode
:
LockFreeLinkedList
Node
<
E
>?
=
null
var
currentNode
:
Node
<
E
>?
=
null
var
currentNode
:
LockFreeLinkedList
Node
<
E
>?
=
null
iterable
.
forEach
{
iterable
.
forEach
{
val
nextNode
=
it
.
asNode
(
tail
)
val
nextNode
=
it
.
asNode
(
tail
)
if
(
firstNode
==
null
)
{
if
(
firstNode
==
null
)
{
...
@@ -166,9 +166,9 @@ open class LockFreeLinkedList<E> {
...
@@ -166,9 +166,9 @@ open class LockFreeLinkedList<E> {
*/
*/
@Suppress
(
"DuplicatedCode"
)
@Suppress
(
"DuplicatedCode"
)
open
fun
addAll
(
iterable
:
Sequence
<
E
>)
{
open
fun
addAll
(
iterable
:
Sequence
<
E
>)
{
var
firstNode
:
Node
<
E
>?
=
null
var
firstNode
:
LockFreeLinkedList
Node
<
E
>?
=
null
var
currentNode
:
Node
<
E
>?
=
null
var
currentNode
:
LockFreeLinkedList
Node
<
E
>?
=
null
iterable
.
forEach
{
iterable
.
forEach
{
val
nextNode
=
it
.
asNode
(
tail
)
val
nextNode
=
it
.
asNode
(
tail
)
if
(
firstNode
==
null
)
{
if
(
firstNode
==
null
)
{
...
@@ -190,7 +190,7 @@ open class LockFreeLinkedList<E> {
...
@@ -190,7 +190,7 @@ open class LockFreeLinkedList<E> {
val
node
=
LazyNode
(
tail
,
supplier
)
val
node
=
LazyNode
(
tail
,
supplier
)
while
(
true
)
{
while
(
true
)
{
var
current
:
Node
<
E
>
=
head
var
current
:
LockFreeLinkedList
Node
<
E
>
=
head
findLastNode
@
while
(
true
)
{
findLastNode
@
while
(
true
)
{
if
(
current
.
isValidElementNode
()
&&
filter
(
current
.
nodeValue
))
if
(
current
.
isValidElementNode
()
&&
filter
(
current
.
nodeValue
))
...
@@ -208,13 +208,14 @@ open class LockFreeLinkedList<E> {
...
@@ -208,13 +208,14 @@ open class LockFreeLinkedList<E> {
}
}
@PublishedApi
// limitation by atomicfu
@PublishedApi
// limitation by atomicfu
internal
fun
<
E
>
Node
<
E
>.
compareAndSetNextNodeRef
(
expect
:
Node
<
E
>,
update
:
Node
<
E
>)
=
this
.
nextNodeRef
.
compareAndSet
(
expect
,
update
)
internal
fun
<
E
>
LockFreeLinkedListNode
<
E
>.
compareAndSetNextNodeRef
(
expect
:
LockFreeLinkedListNode
<
E
>,
update
:
LockFreeLinkedListNode
<
E
>)
=
this
.
nextNodeRef
.
compareAndSet
(
expect
,
update
)
override
fun
toString
():
String
=
joinToString
()
override
fun
toString
():
String
=
joinToString
()
@Suppress
(
"unused"
)
@Suppress
(
"unused"
)
internal
fun
getLinkStructure
():
String
=
buildString
{
internal
fun
getLinkStructure
():
String
=
buildString
{
head
.
childIterateReturnsLastSatisfying
<
Node
<
*
>>({
head
.
childIterateReturnsLastSatisfying
<
LockFreeLinkedList
Node
<
*
>>({
append
(
it
.
toString
())
append
(
it
.
toString
())
append
(
" <- "
)
append
(
" <- "
)
it
.
nextNode
it
.
nextNode
...
@@ -240,7 +241,7 @@ open class LockFreeLinkedList<E> {
...
@@ -240,7 +241,7 @@ open class LockFreeLinkedList<E> {
// physically remove: try to fix the link
// physically remove: try to fix the link
var
next
:
Node
<
E
>
=
toRemove
.
nextNode
var
next
:
LockFreeLinkedList
Node
<
E
>
=
toRemove
.
nextNode
while
(
next
!==
tail
&&
next
.
isRemoved
())
{
while
(
next
!==
tail
&&
next
.
isRemoved
())
{
next
=
next
.
nextNode
next
=
next
.
nextNode
}
}
...
@@ -269,7 +270,7 @@ open class LockFreeLinkedList<E> {
...
@@ -269,7 +270,7 @@ open class LockFreeLinkedList<E> {
// physically remove: try to fix the link
// physically remove: try to fix the link
var
next
:
Node
<
E
>
=
toRemove
.
nextNode
var
next
:
LockFreeLinkedList
Node
<
E
>
=
toRemove
.
nextNode
while
(
next
!==
tail
&&
next
.
isRemoved
())
{
while
(
next
!==
tail
&&
next
.
isRemoved
())
{
next
=
next
.
nextNode
next
=
next
.
nextNode
}
}
...
@@ -282,7 +283,7 @@ open class LockFreeLinkedList<E> {
...
@@ -282,7 +283,7 @@ open class LockFreeLinkedList<E> {
/**
/**
* 动态计算的大小
* 动态计算的大小
*/
*/
val
size
:
Int
get
()
=
head
.
countChildIterate
<
Node
<
E
>>({
it
.
nextNode
},
{
it
!
is
Tail
})
-
1
// empty head is always included
val
size
:
Int
get
()
=
head
.
countChildIterate
<
LockFreeLinkedList
Node
<
E
>>({
it
.
nextNode
},
{
it
!
is
Tail
})
-
1
// empty head is always included
open
operator
fun
contains
(
element
:
E
):
Boolean
{
open
operator
fun
contains
(
element
:
E
):
Boolean
{
forEach
{
if
(
it
==
element
)
return
true
}
forEach
{
if
(
it
==
element
)
return
true
}
...
@@ -295,7 +296,7 @@ open class LockFreeLinkedList<E> {
...
@@ -295,7 +296,7 @@ open class LockFreeLinkedList<E> {
open
fun
isEmpty
():
Boolean
=
head
.
allMatching
{
it
.
isValidElementNode
().
not
()
}
open
fun
isEmpty
():
Boolean
=
head
.
allMatching
{
it
.
isValidElementNode
().
not
()
}
inline
fun
forEach
(
block
:
(
E
)
->
Unit
)
{
inline
fun
forEach
(
block
:
(
E
)
->
Unit
)
{
var
node
:
Node
<
E
>
=
head
var
node
:
LockFreeLinkedList
Node
<
E
>
=
head
while
(
true
)
{
while
(
true
)
{
if
(
node
===
tail
)
return
if
(
node
===
tail
)
return
node
.
letValueIfValid
(
block
)
node
.
letValueIfValid
(
block
)
...
@@ -303,6 +304,15 @@ open class LockFreeLinkedList<E> {
...
@@ -303,6 +304,15 @@ open class LockFreeLinkedList<E> {
}
}
}
}
inline
fun
forEachNode
(
block
:
(
LockFreeLinkedListNode
<
E
>)
->
Unit
)
{
var
node
:
LockFreeLinkedListNode
<
E
>
=
head
while
(
true
)
{
if
(
node
===
tail
)
return
node
.
letValueIfValid
{
block
(
node
)
}
node
=
node
.
nextNode
}
}
@Suppress
(
"unused"
)
@Suppress
(
"unused"
)
open
fun
clear
()
{
open
fun
clear
()
{
val
first
=
head
.
nextNode
val
first
=
head
.
nextNode
...
@@ -638,14 +648,14 @@ open class LockFreeLinkedList<E> {
...
@@ -638,14 +648,14 @@ open class LockFreeLinkedList<E> {
// region internal
// region internal
@Suppress
(
"NOTHING_TO_INLINE"
)
@Suppress
(
"NOTHING_TO_INLINE"
)
private
inline
fun
<
E
>
E
.
asNode
(
nextNode
:
Node
<
E
>):
Node
<
E
>
=
Node
(
nextNode
,
this
)
private
inline
fun
<
E
>
E
.
asNode
(
nextNode
:
LockFreeLinkedListNode
<
E
>):
LockFreeLinkedListNode
<
E
>
=
LockFreeLinkedList
Node
(
nextNode
,
this
)
/**
/**
* Self-iterate using the [iterator], until [mustBeTrue] returns `false`.
* Self-iterate using the [iterator], until [mustBeTrue] returns `false`.
* Returns the element at the last time when the [mustBeTrue] returns `true`
* Returns the element at the last time when the [mustBeTrue] returns `true`
*/
*/
@PublishedApi
@PublishedApi
internal
inline
fun
<
N
:
Node
<
*
>>
N
.
childIterateReturnsLastSatisfying
(
iterator
:
(
N
)
->
N
,
mustBeTrue
:
(
N
)
->
Boolean
):
N
{
internal
inline
fun
<
N
:
LockFreeLinkedList
Node
<
*
>>
N
.
childIterateReturnsLastSatisfying
(
iterator
:
(
N
)
->
N
,
mustBeTrue
:
(
N
)
->
Boolean
):
N
{
if
(!
mustBeTrue
(
this
))
return
this
if
(!
mustBeTrue
(
this
))
return
this
var
value
:
N
=
this
var
value
:
N
=
this
...
@@ -703,9 +713,9 @@ private inline fun <E> E.countChildIterate(iterator: (E) -> E, mustBeTrue: (E) -
...
@@ -703,9 +713,9 @@ private inline fun <E> E.countChildIterate(iterator: (E) -> E, mustBeTrue: (E) -
@PublishedApi
@PublishedApi
internal
class
LazyNode
<
E
>
@PublishedApi
internal
constructor
(
internal
class
LazyNode
<
E
>
@PublishedApi
internal
constructor
(
nextNode
:
Node
<
E
>,
nextNode
:
LockFreeLinkedList
Node
<
E
>,
private
val
valueComputer
:
()
->
E
private
val
valueComputer
:
()
->
E
)
:
Node
<
E
>(
nextNode
,
null
)
{
)
:
LockFreeLinkedList
Node
<
E
>(
nextNode
,
null
)
{
private
val
initialized
=
atomic
(
false
)
private
val
initialized
=
atomic
(
false
)
private
val
value
:
AtomicRef
<
E
?
>
=
atomic
(
null
)
private
val
value
:
AtomicRef
<
E
?
>
=
atomic
(
null
)
...
@@ -727,20 +737,19 @@ internal class LazyNode<E> @PublishedApi internal constructor(
...
@@ -727,20 +737,19 @@ internal class LazyNode<E> @PublishedApi internal constructor(
}
}
@PublishedApi
@PublishedApi
internal
class
Head
<
E
>(
nextNode
:
Node
<
E
>)
:
Node
<
E
>(
nextNode
,
null
)
{
internal
class
Head
<
E
>(
nextNode
:
LockFreeLinkedListNode
<
E
>)
:
LockFreeLinkedList
Node
<
E
>(
nextNode
,
null
)
{
override
fun
toString
():
String
=
"Head"
override
fun
toString
():
String
=
"Head"
override
val
nodeValue
:
Nothing
get
()
=
error
(
"Internal error: trying to get the value of a Head"
)
override
val
nodeValue
:
Nothing
get
()
=
error
(
"Internal error: trying to get the value of a Head"
)
}
}
@PublishedApi
@PublishedApi
internal
open
class
Tail
<
E
>
:
Node
<
E
>(
null
,
null
)
{
internal
open
class
Tail
<
E
>
:
LockFreeLinkedList
Node
<
E
>(
null
,
null
)
{
override
fun
toString
():
String
=
"Tail"
override
fun
toString
():
String
=
"Tail"
override
val
nodeValue
:
Nothing
get
()
=
error
(
"Internal error: trying to get the value of a Tail"
)
override
val
nodeValue
:
Nothing
get
()
=
error
(
"Internal error: trying to get the value of a Tail"
)
}
}
@PublishedApi
open
class
LockFreeLinkedListNode
<
E
>(
internal
open
class
Node
<
E
>(
nextNode
:
LockFreeLinkedListNode
<
E
>?,
nextNode
:
Node
<
E
>?,
private
var
initialNodeValue
:
E
?
private
var
initialNodeValue
:
E
?
)
{
)
{
/*
/*
...
@@ -754,10 +763,11 @@ internal open class Node<E>(
...
@@ -754,10 +763,11 @@ internal open class Node<E>(
open
val
nodeValue
:
E
get
()
=
initialNodeValue
?:
error
(
"Internal error: nodeValue is not initialized"
)
open
val
nodeValue
:
E
get
()
=
initialNodeValue
?:
error
(
"Internal error: nodeValue is not initialized"
)
val
removed
=
atomic
(
false
)
@PublishedApi
internal
val
removed
=
atomic
(
false
)
@Suppress
(
"LeakingThis"
)
@Suppress
(
"LeakingThis"
)
val
nextNodeRef
:
AtomicRef
<
Node
<
E
>>
=
atomic
(
nextNode
?:
this
)
internal
val
nextNodeRef
:
AtomicRef
<
LockFreeLinkedList
Node
<
E
>>
=
atomic
(
nextNode
?:
this
)
inline
fun
<
R
>
letValueIfValid
(
block
:
(
E
)
->
R
):
R
?
{
inline
fun
<
R
>
letValueIfValid
(
block
:
(
E
)
->
R
):
R
?
{
if
(!
this
.
isValidElementNode
())
{
if
(!
this
.
isValidElementNode
())
{
...
@@ -770,7 +780,8 @@ internal open class Node<E>(
...
@@ -770,7 +780,8 @@ internal open class Node<E>(
/**
/**
* Short cut for accessing [nextNodeRef]
* Short cut for accessing [nextNodeRef]
*/
*/
var
nextNode
:
Node
<
E
>
@PublishedApi
internal
var
nextNode
:
LockFreeLinkedListNode
<
E
>
get
()
=
nextNodeRef
.
value
get
()
=
nextNodeRef
.
value
set
(
value
)
{
set
(
value
)
{
nextNodeRef
.
value
=
value
nextNodeRef
.
value
=
value
...
@@ -779,7 +790,7 @@ internal open class Node<E>(
...
@@ -779,7 +790,7 @@ internal open class Node<E>(
/**
/**
* Returns the former node of the last node whence [filter] returns true
* Returns the former node of the last node whence [filter] returns true
*/
*/
inline
fun
iterateBeforeFirst
(
filter
:
(
Node
<
E
>)
->
Boolean
):
Node
<
E
>
=
inline
fun
iterateBeforeFirst
(
filter
:
(
LockFreeLinkedListNode
<
E
>)
->
Boolean
):
LockFreeLinkedList
Node
<
E
>
=
this
.
childIterateReturnsLastSatisfying
({
it
.
nextNode
},
{
!
filter
(
it
)
})
this
.
childIterateReturnsLastSatisfying
({
it
.
nextNode
},
{
!
filter
(
it
)
})
/**
/**
...
@@ -788,7 +799,8 @@ internal open class Node<E>(
...
@@ -788,7 +799,8 @@ internal open class Node<E>(
* Head, which is this, is also being tested.
* Head, which is this, is also being tested.
* [Tail], is not being tested.
* [Tail], is not being tested.
*/
*/
inline
fun
allMatching
(
condition
:
(
Node
<
E
>)
->
Boolean
):
Boolean
=
this
.
childIterateReturnsLastSatisfying
({
it
.
nextNode
},
condition
)
!
is
Tail
inline
fun
allMatching
(
condition
:
(
LockFreeLinkedListNode
<
E
>)
->
Boolean
):
Boolean
=
this
.
childIterateReturnsLastSatisfying
({
it
.
nextNode
},
condition
)
!
is
Tail
/**
/**
* Stop on and returns the former element of the element that is [equals] to the [element]
* Stop on and returns the former element of the element that is [equals] to the [element]
...
@@ -796,23 +808,23 @@ internal open class Node<E>(
...
@@ -796,23 +808,23 @@ internal open class Node<E>(
* E.g.: for `head <- 1 <- 2 <- 3 <- tail`, `iterateStopOnNodeValue(2)` returns the node whose value is 1
* E.g.: for `head <- 1 <- 2 <- 3 <- tail`, `iterateStopOnNodeValue(2)` returns the node whose value is 1
*/
*/
@Suppress
(
"NOTHING_TO_INLINE"
)
@Suppress
(
"NOTHING_TO_INLINE"
)
internal
inline
fun
iterateBeforeNodeValue
(
element
:
E
):
Node
<
E
>
=
this
.
iterateBeforeFirst
{
it
.
isValidElementNode
()
&&
it
.
nodeValue
==
element
}
internal
inline
fun
iterateBeforeNodeValue
(
element
:
E
):
LockFreeLinkedListNode
<
E
>
=
this
.
iterateBeforeFirst
{
it
.
isValidElementNode
()
&&
it
.
nodeValue
==
element
}
}
}
@PublishedApi
// DO NOT INLINE: ATOMIC OPERATION
fun
<
E
>
LockFreeLinkedListNode
<
E
>.
isRemoved
()
=
this
.
removed
.
value
internal
fun
<
E
>
Node
<
E
>.
isRemoved
()
=
this
.
removed
.
value
@PublishedApi
@PublishedApi
@Suppress
(
"NOTHING_TO_INLINE"
)
@Suppress
(
"NOTHING_TO_INLINE"
)
internal
inline
fun
Node
<*>.
isValidElementNode
():
Boolean
=
!
isHead
()
&&
!
isTail
()
&&
!
isRemoved
()
internal
inline
fun
LockFreeLinkedList
Node
<*>.
isValidElementNode
():
Boolean
=
!
isHead
()
&&
!
isTail
()
&&
!
isRemoved
()
@PublishedApi
@PublishedApi
@Suppress
(
"NOTHING_TO_INLINE"
)
@Suppress
(
"NOTHING_TO_INLINE"
)
internal
inline
fun
Node
<*>.
isHead
():
Boolean
=
this
is
Head
internal
inline
fun
LockFreeLinkedList
Node
<*>.
isHead
():
Boolean
=
this
is
Head
@PublishedApi
@PublishedApi
@Suppress
(
"NOTHING_TO_INLINE"
)
@Suppress
(
"NOTHING_TO_INLINE"
)
internal
inline
fun
Node
<*>.
isTail
():
Boolean
=
this
is
Tail
internal
inline
fun
LockFreeLinkedList
Node
<*>.
isTail
():
Boolean
=
this
is
Tail
// end region
// end region
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment