Skip to content

Commit

Permalink
Fix I2892: Implement sys/select pselect method (#2895)
Browse files Browse the repository at this point in the history
  • Loading branch information
LeeTibbert committed Oct 10, 2022
1 parent 5438abb commit 427fea4
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 22 deletions.
2 changes: 2 additions & 0 deletions posixlib/src/main/resources/scala-native/sys/select.c
Expand Up @@ -65,6 +65,8 @@ int scalanative_fd_isset(int fd, struct scalanative_fd_set *set) {
return FD_ISSET(fd, (fd_set *)set);
}

// pselect() is straight call through, so no declaration here.

int scalanative_select(int nfds, struct scalanative_fd_set *readfds,
struct scalanative_fd_set *writefds,
struct scalanative_fd_set *exceptfds,
Expand Down
76 changes: 54 additions & 22 deletions posixlib/src/main/scala/scala/scalanative/posix/sys/select.scala
@@ -1,17 +1,32 @@
package scala.scalanative.posix.sys
package scala.scalanative
package posix
package sys

import scalanative.unsafe._
import scalanative.unsafe.Nat._

/** POSIX select.h for Scala
*
* @see
* The Open Group Base Specifications
* [[https://pubs.opengroup.org/onlinepubs/9699919799 Issue 7, 2018]]
* edition.
*/
@extern
object select {

// posix requires this file declares suseconds_t. Use single point of truth.
// Use single points of truth for types required by POSIX specification.

type time_t = types.time_t
type suseconds_t = types.suseconds_t

type sigset_t = posix.signal.sigset_t

type timespec = posix.time.timespec
type timeval = sys.time.timeval

// The declaration of type fd_set closely follows the Linux C declaration.
// glibc circa March 2019 and many years prior is documented as using a
// glibc, circa March 2019 and many years prior, is documented as using a
// fixed buffer of 1024 bits.
//
// Since "extern object may only contain extern fields and methods"
Expand All @@ -28,26 +43,43 @@ object select {

type fd_set = CStruct1[CArray[CLongInt, _16]]

// Allocation & usage example:
//
// An fd_set is arguably too large to allocate on the stack, so use a Zone.
//
// import scalanative.unsafe.{Zone, alloc}
//
// Zone {
//
// // Zone.alloc is documented as returning zeroed memory.
// val fdsetPtr = alloc[fd_set] // No need to FD_ZERO.
// FD_SET(sock, fdsetPtr)
//
// // If used, allocate writefds and/or exceptfds the same way.
//
// val result = select(nfds, fdsetPtr, writefds, exceptfds)
// // check result.
// // do work implied by result.
//
// } // fdsetPtr and memory it points to are not valid outsize of Zone.
/* Allocation & usage example:
*
* An fd_set is arguably too large to allocate on the stack, so use a Zone.
*
* import scalanative.unsafe.{Zone, alloc}
*
* Zone {
* // Zone.alloc is documented as returning zeroed memory.
* val fdsetPtr = alloc[fd_set] // No need to FD_ZERO.
* FD_SET(sock, fdsetPtr)
*
* // If used, allocate writefds and/or exceptfds the same way.
*
* val result = select(nfds, fdsetPtr, writefds, exceptfds, timeout)
* // check result.
* // do work implied by result.
*
* } // fdsetPtr and memory it points to are not valid outsize of Zone.
*/

/* Declare pselect() as a direct call through to C. There no
* @name("scalanative_pselect") is needed.
* Guard code exists to ensure match with operating system at compile time.
* fd_set is guarded by code in select.c
* timespec is guarded by code in time.c (distinct from sys/time.c)
*/

def pselect(
nfds: CInt,
readfds: Ptr[fd_set],
writefds: Ptr[fd_set],
exceptfds: Ptr[fd_set],
timeout: Ptr[timespec],
sigmask: sigset_t
): CInt = extern

// select() is a excellent candidate to be changed to use direct call-thru.
@name("scalanative_select")
def select(
nfds: CInt,
Expand Down

0 comments on commit 427fea4

Please sign in to comment.