All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scala.scalanative.posix.sys.select.scala Maven / Gradle / Ivy

There is a newer version: 0.5.5
Show newest version
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
@define("__SCALANATIVE_POSIX_SYS_SELECT")
object select {

  // 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
  // fixed buffer of 1024 bits.
  //
  // Since "extern object may only contain extern fields and methods"
  // a runtime check can not be done here. Instead, a compile time check
  // is done in posix/sys/select.c. That detects mismatches on the
  // compilation system, but may miss mismatches on the executing system.
  //
  // The more recent posix poll() avoids issues with FD_SETSIZE and offers
  // performance advantages. However, sometimes ya just gotta select().

  // Linux specifies an array of 64 bit longs.
  // 16 * 64 == 1024 == FD_SETSIZE.
  private type _16 = Digit2[_1, _6]

  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, 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,
      readfds: Ptr[fd_set],
      writefds: Ptr[fd_set],
      exceptfds: Ptr[fd_set],
      timeout: Ptr[time.timeval]
  ): CInt = extern

  @name("scalanative_fd_setsize")
  def FD_SETSIZE: CInt = extern

  @name("scalanative_fd_clr")
  def FD_CLR(fd: CInt, set: Ptr[fd_set]): Unit = extern

  @name("scalanative_fd_isset")
  def FD_ISSET(fd: CInt, set: Ptr[fd_set]): CInt = extern

  @name("scalanative_fd_set")
  def FD_SET(fd: CInt, set: Ptr[fd_set]): Unit = extern

  @name("scalanative_fd_zero")
  def FD_ZERO(set: Ptr[fd_set]): Unit = extern

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy