Skip to content

Commit 606d020

Browse files
authored
Use separate methods for Poll read, write and readWrite (#34)
* Use separate methods for Poll read, write and readWrite * Reintroduce start with dynamic in and out * Bump utest to 0.7.5 * Add PollTests
1 parent 0c41132 commit 606d020

File tree

4 files changed

+94
-18
lines changed

4 files changed

+94
-18
lines changed

build.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ lazy val commonSettings = Seq(
4444
"-Ywarn-unused-import"
4545
),
4646
Compile / doc / scalacOptions -= "-Xfatal-warnings",
47-
libraryDependencies += "com.lihaoyi" %%% "utest" % "0.7.4" % Test,
47+
libraryDependencies += "com.lihaoyi" %%% "utest" % "0.7.5" % Test,
4848
testFrameworks += new TestFramework("utest.runner.Framework"),
4949
Test / nativeLinkStubs := true,
5050
publish / skip := true,

client/curl.scala

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -178,20 +178,20 @@ object Curl {
178178
new Poll(socket_data)
179179
}
180180

181-
val readable = action == POLL_IN || action == POLL_INOUT
182-
val writable = action == POLL_OUT || action == POLL_INOUT
181+
val in = action == POLL_IN || action == POLL_INOUT
182+
val out = action == POLL_OUT || action == POLL_INOUT
183183

184-
if (readable || writable) {
184+
if (in || out) {
185185
println(
186-
s"starting poll with readable = $readable and writable = $writable"
186+
s"starting poll with in = $in and out = $out"
187187
)
188-
pollHandle.start(readable, writable) { (status, readable, writable) =>
188+
pollHandle.start(in, out) { res =>
189189
println(
190-
s"ready_for_curl fired with status $status and readable = $readable writable = $writable"
190+
s"ready_for_curl fired with status ${res.result} and readable = ${res.readable} writable = ${res.writable}"
191191
)
192192
var actions = 0
193-
if (readable) actions |= 1
194-
if (writable) actions |= 2
193+
if (res.readable) actions |= 1
194+
if (res.writable) actions |= 2
195195
val running_handles = stackalloc[Int]
196196
val result =
197197
multi_socket_action(multi, socket, actions, running_handles)

core/src/main/scala/scala/scalanative/loop/Poll.scala

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,29 @@ import LibUV._, LibUVConstants._
55
import scala.scalanative.unsafe.Ptr
66
import internals.HandleUtils
77

8+
class RWResult(val result: Int, val readable: Boolean, val writable: Boolean)
89
@inline class Poll(val ptr: Ptr[Byte]) extends AnyVal {
9-
def start(in: Boolean, out: Boolean)(
10-
callback: (Int, Boolean, Boolean) => Unit
11-
): Unit = {
10+
def start(in: Boolean, out: Boolean)(callback: RWResult => Unit): Unit = {
1211
HandleUtils.setData(ptr, callback)
1312
var events = 0
1413
if (out) events |= UV_WRITABLE
1514
if (in) events |= UV_READABLE
16-
uv_poll_start(ptr, events, Poll.pollCB)
15+
uv_poll_start(ptr, events, Poll.pollReadWriteCB)
16+
}
17+
18+
def startReadWrite(callback: RWResult => Unit): Unit = {
19+
HandleUtils.setData(ptr, callback)
20+
uv_poll_start(ptr, UV_READABLE | UV_WRITABLE, Poll.pollReadWriteCB)
21+
}
22+
23+
def startRead(callback: Int => Unit): Unit = {
24+
HandleUtils.setData(ptr, callback)
25+
uv_poll_start(ptr, UV_READABLE, Poll.pollReadCB)
26+
}
27+
28+
def startWrite(callback: Int => Unit): Unit = {
29+
HandleUtils.setData(ptr, callback)
30+
uv_poll_start(ptr, UV_WRITABLE, Poll.pollWriteCB)
1731
}
1832

1933
def stop(): Unit = {
@@ -23,17 +37,31 @@ import internals.HandleUtils
2337
}
2438

2539
object Poll {
26-
private val pollCB = new PollCB {
40+
private val pollReadWriteCB = new PollCB {
2741
def apply(handle: PollHandle, status: Int, events: Int): Unit = {
2842
val callback =
29-
HandleUtils.getData[(Int, Boolean, Boolean) => Unit](handle)
43+
HandleUtils.getData[RWResult => Unit](handle)
3044
callback.apply(
31-
status,
32-
(events & UV_READABLE) != 0,
33-
(events & UV_WRITABLE) != 0
45+
new RWResult(
46+
result = status,
47+
readable = (events & UV_READABLE) != 0,
48+
writable = (events & UV_WRITABLE) != 0
49+
)
3450
)
3551
}
3652
}
53+
private val pollReadCB = new PollCB {
54+
def apply(handle: PollHandle, status: Int, events: Int): Unit = {
55+
val callback = HandleUtils.getData[Int => Unit](handle)
56+
if ((events & UV_READABLE) != 0) callback.apply(status)
57+
}
58+
}
59+
private val pollWriteCB = new PollCB {
60+
def apply(handle: PollHandle, status: Int, events: Int): Unit = {
61+
val callback = HandleUtils.getData[Int => Unit](handle)
62+
if ((events & UV_WRITABLE) != 0) callback.apply(status)
63+
}
64+
}
3765

3866
private lazy val size = uv_handle_size(UV_POLL_T)
3967

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package scala.scalanative.loop
2+
3+
import utest._
4+
import scala.scalanative.unsafe._
5+
import scala.scalanative.posix.unistd._
6+
import scala.concurrent.ExecutionContext.Implicits.global
7+
import scala.concurrent.{Future, Promise}
8+
9+
object PollTests extends LoopTestSuite {
10+
def usingPipe(f: (Int, Int) => Future[Unit]): Future[Unit] = {
11+
val fildes = stackalloc[CInt](2)
12+
if (pipe(fildes) != 0) {
13+
throw new Exception("Failed to create pipe")
14+
}
15+
val future = f(fildes(0), fildes(1))
16+
future.onComplete { _ =>
17+
close(fildes(0))
18+
close(fildes(1))
19+
}
20+
future
21+
}
22+
23+
val tests = Tests {
24+
test("startRead") {
25+
usingPipe { (r, w) =>
26+
val promise = Promise[Unit]()
27+
val byte = 10.toByte
28+
val poll = Poll(r)
29+
poll.startRead { i =>
30+
if (i != 0) {
31+
throw new Exception("Poll result != 0")
32+
}
33+
val buf = stackalloc[Byte]
34+
val bytesRead = read(r, buf, 1)
35+
assert(bytesRead == 1)
36+
assert(buf(0) == byte)
37+
promise.success(())
38+
poll.stop()
39+
}
40+
val buf = stackalloc[Byte]
41+
buf(0) = byte
42+
val bytesWrote = write(w, buf, 1)
43+
assert(bytesWrote == 1)
44+
promise.future
45+
}
46+
}
47+
}
48+
}

0 commit comments

Comments
 (0)