--
--	An IO scheduler for occam-pi
--	Copyright (C) 2008, 2009 Adam Sampson <ats@offog.org>
--
--	This library is free software; you can redistribute it and/or
--	modify it under the terms of the GNU Lesser General Public
--	License as published by the Free Software Foundation, either
--	version 2 of the License, or (at your option) any later version.
--
--	This library is distributed in the hope that it will be useful,
--	but WITHOUT ANY WARRANTY; without even the implied warranty of
--	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
--	Lesser General Public License for more details.
--
--	You should have received a copy of the GNU Lesser General Public
--	License along with this library.  If not, see
--	<http://www.gnu.org/licenses/>.
--

--** @module selector

#INCLUDE "cif.module"
#INCLUDE "selector.inc"

--{{{  externs
#PRAGMA EXTERNAL "PROC CIF.selector.make.nonblocking (VAL INT fd) = 4096"
#PRAGMA EXTERNAL "PROC CIF.selector.server (SELECTOR.CT? svr) = 16384"
--}}}

--{{{  PROC selector.make.nonblocking
--* Make a file descriptor non-blocking.
-- This just sets the [@ref O.NONBLOCK] flag on the FD.
-- @param fd File descriptor
PROC selector.make.nonblocking (VAL INT fd)
  -- Dummy variable necessary owing to occ21 bug.
  INITIAL INT real.fd IS fd:
  CIF.selector.make.nonblocking (real.fd)
:
--}}}
--{{{  PROC selector.add
--* Register a file descriptor with a selector.
PROC selector.add (SHARED SELECTOR.CT! sel, VAL INT fd, events, RESULT SELECTOR.SIGNAL? svr)
  SELECTOR.SIGNAL! cli:
  SEQ
    cli, svr := MOBILE SELECTOR.SIGNAL
    CLAIM sel
      sel[req] ! add; fd; events; cli
:
--}}}
--{{{  PROC selector.delayed.add
--* Register a file descriptor with a selector, then send the new signal end
-- down a shared channel.
--
-- Why would you want to do this? It's to avoid a client-server loop if you've
-- got a client that wants to change the set of FDs it selects on: rather
-- than having it add the FD itself (which would mean switching the direction
-- of the client-server relationship), have it fork off this process.
PROC selector.delayed.add (SHARED SELECTOR.CT! sel, VAL INT fd, events, SHARED CHAN SELECTOR.SIGNAL? svr.out!)
  SELECTOR.SIGNAL? svr:
  SEQ
    selector.add (sel, fd, events, svr)
    CLAIM svr.out!
      svr.out ! svr
:
--}}}
--{{{  PROC selector.start
--* Start an IO selector.
PROC selector.start (RESULT SHARED SELECTOR.CT! sel)
  SELECTOR.CT? svr:
  SEQ
    sel, svr := MOBILE SELECTOR.CT
    -- Wrapper PROC necessary owing to occ21 bug.
    PROC t (SELECTOR.CT? svr)
      CIF.selector.server (svr)
    :
    FORK t (svr)
:
--}}}
