-
Notifications
You must be signed in to change notification settings - Fork 535
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
28 changed files
with
651 additions
and
673 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 7 additions & 0 deletions
7
core/jvm-native/src/main/scala/cats/effect/unsafe/Poller.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package cats.effect.unsafe | ||
|
||
trait Poller { | ||
def poll(limitNanos: Long): Boolean | ||
def interrupt(targetThread: Thread): Unit | ||
def close(): Unit | ||
} |
5 changes: 5 additions & 0 deletions
5
core/jvm-native/src/main/scala/cats/effect/unsafe/PollingRuntime.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package cats.effect.unsafe | ||
|
||
abstract class PollingRuntime[+P <: Poller] { | ||
def buildPoller(reportFailure: Throwable => Unit): P | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 7 additions & 0 deletions
7
core/jvm-native/src/main/scala/cats/effect/unsafe/RuntimeContext.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package cats.effect.unsafe | ||
|
||
import scala.concurrent.ExecutionContext | ||
|
||
trait RuntimeContext[+P] extends ExecutionContext { | ||
def register(cb: P => Unit): Unit | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
95 changes: 95 additions & 0 deletions
95
core/jvm/src/main/scala/cats/effect/unsafe/SelectorPoller.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
package cats.effect | ||
package unsafe | ||
|
||
import java.nio.channels.SelectableChannel | ||
import java.nio.channels.spi.AbstractSelector | ||
|
||
final class SelectorPoller( | ||
selector: AbstractSelector)( | ||
reportFailure: Throwable => Unit) | ||
extends Poller { | ||
|
||
import SelectorPoller.CallbackNode | ||
|
||
def close(): Unit = | ||
selector.close() | ||
|
||
def interrupt(targetThread: Thread): Unit = { | ||
selector.wakeup() | ||
() | ||
} | ||
|
||
def poll(nanos: Long): Boolean = { | ||
val millis = if (nanos >= 0) nanos / 1000000 else -1 | ||
|
||
if (millis == 0) selector.selectNow() | ||
else if (millis > 0) selector.select(millis) | ||
else selector.select() | ||
|
||
if (selector.isOpen()) { // closing selector interrupts select | ||
val ready = selector.selectedKeys().iterator() | ||
while (ready.hasNext()) { | ||
val key = ready.next() | ||
ready.remove() | ||
|
||
val readyOps = key.readyOps() | ||
|
||
var head: CallbackNode = null | ||
var prev: CallbackNode = null | ||
var node = key.attachment().asInstanceOf[CallbackNode] | ||
while (node ne null) { | ||
val next = node.next | ||
|
||
if ((node.interest & readyOps) != 0) { // execute callback and drop this node | ||
val cb = node.callback | ||
if (cb != null) cb(readyOps) | ||
if (prev ne null) prev.next = next | ||
} else { // keep this node | ||
prev = node | ||
if (head eq null) | ||
head = node | ||
} | ||
|
||
node = next | ||
} | ||
|
||
// reset interest in triggered ops | ||
key.interestOps(key.interestOps() & ~readyOps) | ||
key.attach(head) | ||
} | ||
|
||
!selector.keys().isEmpty() | ||
} else false | ||
} | ||
|
||
def select(ch: SelectableChannel, ops: Int)(cb: Int => Unit): () => Unit = { | ||
val key = ch.keyFor(selector) | ||
|
||
val node = if (key eq null) { // not yet registered on this selector | ||
val node = new CallbackNode(ops, cb, null) | ||
ch.register(selector, ops, node) | ||
node | ||
} else { // existing key | ||
// mixin the new interest | ||
key.interestOps(key.interestOps() | ops) | ||
val node = | ||
new CallbackNode(ops, cb, key.attachment().asInstanceOf[CallbackNode]) | ||
key.attach(node) | ||
node | ||
} | ||
|
||
{ () => | ||
// set all interest bits | ||
node.interest = -1 | ||
// clear for gc | ||
node.callback = null | ||
} | ||
} | ||
} | ||
|
||
private object SelectorPoller { | ||
private[SelectorPoller] final class CallbackNode( | ||
var interest: Int, | ||
var callback: Int => Unit, | ||
var next: CallbackNode) | ||
} |
Oops, something went wrong.