Skip to content

Commit

Permalink
ch05, refactored common parts
Browse files Browse the repository at this point in the history
  • Loading branch information
spamegg1 committed Apr 7, 2024
1 parent c09d8db commit ade0e27
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 28 deletions.
31 changes: 6 additions & 25 deletions src/main/scala/ch05/blockingServer.scala
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
package ch05.blockingServer

import scalanative.unsafe.{sizeof, Ptr, CQuote}
import scalanative.unsigned.{UShort, toUShort, toCSize}
import scalanative.unsafe.{sizeof, Ptr}
import scalanative.unsigned.{UShort, toUShort}
import scalanative.libc.stdlib.malloc
import scalanative.libc.stdio.EOF
import scalanative.libc.string.strlen
import scalanative.posix.unistd
import scalanative.posix.sys.socket
import socket.{AF_INET, SOCK_STREAM, sockaddr}
import scalanative.posix.netinet.in.{sockaddr_in, INADDR_ANY}
import scalanative.posix.arpa.inet

import ch05.common.handleConnection

def serve(port: UShort): Unit =
// Allocate and initialize the server address
val addrSize = sizeof[sockaddr_in]
Expand All @@ -30,28 +30,9 @@ def serve(port: UShort): Unit =
println(s"listen returned $listenResult")
println(s"accepting connections on port $port")

// Main accept() loop
while true do
while true do // Main accept() loop
val connectionFd = socket.accept(sockFd, null, null)
println(s"accept returned fd $connectionFd")
// we will replace handleConnection with fork_and_handle shortly
handleConnection(connectionFd)
handleConnection(connectionFd) // we will replace this with forkAndHandle shortly

unistd.close(sockFd)

def handleConnection(connSocket: Int, maxSize: Int = 1024): Unit =
import scala.util.boundary, boundary.break

val message = c"Connection accepted! Enter a message and it will be echoed back\n"
val promptWrite = unistd.write(connSocket, message, strlen(message))
val lineBuffer = malloc(maxSize) // this is never freed, program ends before it can be.

boundary:
while true do
val bytesRead = unistd.read(connSocket, lineBuffer, maxSize.toCSize) // 0.5
println(s"read $bytesRead bytes")

if bytesRead == EOF then break() // connection has been closed by the client

val bytesWritten = unistd.write(connSocket, lineBuffer, bytesRead.toCSize) // 0.5
println(s"wrote $bytesWritten bytes")
25 changes: 25 additions & 0 deletions src/main/scala/ch05/common.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package ch05.common

import scalanative.unsigned.UnsignedRichInt // .toCSize
import scalanative.unsafe.CQuote
import scalanative.posix.unistd
import scalanative.libc.stdlib.malloc
import scalanative.libc.string.strlen
import scalanative.libc.stdio.EOF

import util.boundary, boundary.break

def handleConnection(connSocket: Int, maxSize: Int = 1024): Unit =
val message = c"Connection accepted! Enter a message and it will be echoed back\n"
val promptWrite = unistd.write(connSocket, message, strlen(message))
val lineBuffer = malloc(maxSize) // this is never freed, program ends before it can be.

boundary:
while true do
val bytesRead = unistd.read(connSocket, lineBuffer, maxSize.toCSize) // 0.5
println(s"read $bytesRead bytes")

if bytesRead == EOF then break() // connection has been closed by the client

val bytesWritten = unistd.write(connSocket, lineBuffer, bytesRead.toCSize) // 0.5
println(s"wrote $bytesWritten bytes")
8 changes: 5 additions & 3 deletions src/main/scala/ch05/forkServer.scala
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package ch05.examples

import scalanative.unsafe.stackalloc
import scalanative.posix.unistd
import scalanative.posix.sys.wait.WNOHANG

import ch04.common.util.{fork, waitpid}
import ch05.blockingServer.handleConnection
import ch05.common.handleConnection

def forkAndHandle(connectionFd: Int, maxSize: Int = 1024): Unit =
val pid = fork()
Expand All @@ -12,9 +14,9 @@ def forkAndHandle(connectionFd: Int, maxSize: Int = 1024): Unit =
unistd.close(connectionFd)
cleanupChildren
else // In child process
println("fork returned $pid, in child process")
println(s"fork returned $pid, in child process")
handleConnection(connectionFd, maxSize)
sys.exit()
sys.exit() // this is scala.sys, not posix.sys

@annotation.tailrec
def cleanupChildren: Unit =
Expand Down

0 comments on commit ade0e27

Please sign in to comment.