summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--doc/lib.txt2
-rw-r--r--doc/manual.txt12
-rw-r--r--doc/nimrodc.txt2
-rw-r--r--koch.nim2
-rw-r--r--lib/pure/selectors.nim36
5 files changed, 37 insertions, 17 deletions
diff --git a/doc/lib.txt b/doc/lib.txt
index 3ca519c9e..2da753007 100644
--- a/doc/lib.txt
+++ b/doc/lib.txt
@@ -535,7 +535,7 @@ Database support
 * `odbcsql <odbcsql.html>`_
   interface to the ODBC driver.
 * `sphinx <sphinx.html>`_
-  Nimrod wrapper for ``shpinx``.
+  Nimrod wrapper for ``sphinx``.
 
 
 XML Processing
diff --git a/doc/manual.txt b/doc/manual.txt
index 39e2bad2a..d3a330e3a 100644
--- a/doc/manual.txt
+++ b/doc/manual.txt
@@ -123,7 +123,7 @@ This means that all the control structures are recognized by indentation.
 Indentation consists only of spaces; tabulators are not allowed.
 
 The indentation handling is implemented as follows: The lexer annotates the
-following token with the preceeding number of spaces; indentation is not
+following token with the preceding number of spaces; indentation is not
 a separate token. This trick allows parsing of Nimrod with only 1 token of
 lookahead.
 
@@ -617,7 +617,7 @@ Ordinal types
 
 Integers, bool, characters and enumeration types (and subranges of these
 types) belong to ordinal types. For reasons of simplicity of implementation
-the types ``uint`` and ``uint64`` are no ordinal types.
+the types ``uint`` and ``uint64`` are not ordinal types.
 
 
 Pre-defined integer types
@@ -686,7 +686,7 @@ kinds of integer types are used: the smaller type is converted to the larger.
 A `narrowing type conversion`:idx: converts a larger to a smaller type (for
 example ``int32 -> int16``. A `widening type conversion`:idx: converts a 
 smaller type to a larger type (for example ``int16 -> int32``). In Nimrod only
-widening type conversion are *implicit*:
+widening type conversions are *implicit*:
 
 .. code-block:: nimrod
   var myInt16 = 5i16
@@ -1519,7 +1519,7 @@ Most calling conventions exist only for the Windows 32-bit platform.
 
 Assigning/passing a procedure to a procedural variable is only allowed if one
 of the following conditions hold:
-1) The procedure that is accessed resists in the current module.
+1) The procedure that is accessed resides in the current module.
 2) The procedure is marked with the ``procvar`` pragma (see `procvar pragma`_).
 3) The procedure has a calling convention that differs from ``nimcall``.
 4) The procedure is anonymous.
@@ -1527,8 +1527,8 @@ of the following conditions hold:
 The rules' purpose is to prevent the case that extending a non-``procvar`` 
 procedure with default parameters breaks client code.
 
-The default calling convention is ``nimcall``, unless it is an inner proc (
-a proc inside of a proc). For an inner proc an analysis is performed whether it
+The default calling convention is ``nimcall``, unless it is an inner proc (a
+proc inside of a proc). For an inner proc an analysis is performed whether it
 accesses its environment. If it does so, it has the calling convention
 ``closure``, otherwise it has the calling convention ``nimcall``.
 
diff --git a/doc/nimrodc.txt b/doc/nimrodc.txt
index 52e0a6eaf..d1925547e 100644
--- a/doc/nimrodc.txt
+++ b/doc/nimrodc.txt
@@ -167,7 +167,7 @@ might contain some cruft even when dead code elimination is turned on. So
 the final release build should be done with ``--symbolFiles:off``.

 

 Due to the aggregation of C code it is also recommended that each project

-resists in its own directory so that the generated ``nimcache`` directory

+resides in its own directory so that the generated ``nimcache`` directory

 is not shared between different projects.

 

 

diff --git a/koch.nim b/koch.nim
index 79acc7791..c203e0fd0 100644
--- a/koch.nim
+++ b/koch.nim
@@ -167,7 +167,7 @@ const
   cleanExt = [
     ".ppu", ".o", ".obj", ".dcu", ".~pas", ".~inc", ".~dsk", ".~dpr",
     ".map", ".tds", ".err", ".bak", ".pyc", ".exe", ".rod", ".pdb", ".idb",
-    ".idx"
+    ".idx", ".ilk"
   ]
   ignore = [
     ".bzrignore", "nimrod", "nimrod.exe", "koch", "koch.exe", ".gitignore"
diff --git a/lib/pure/selectors.nim b/lib/pure/selectors.nim
index f630ba235..498f41e83 100644
--- a/lib/pure/selectors.nim
+++ b/lib/pure/selectors.nim
@@ -49,9 +49,10 @@ when defined(linux) or defined(nimdoc):
     ## Registers file descriptor ``fd`` to selector ``s`` with a set of TEvent
     ## ``events``.
     var event = createEventStruct(events, fd)
-    if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, fd, addr(event)) != 0:
-      OSError(OSLastError())
-  
+    if events != {}:
+      if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, fd, addr(event)) != 0:
+        OSError(OSLastError())
+
     var key = PSelectorKey(fd: fd, events: events, data: data)
   
     s.fds[fd] = key
@@ -61,11 +62,27 @@ when defined(linux) or defined(nimdoc):
       events: set[TEvent]): PSelectorKey {.discardable.} =
     ## Updates the events which ``fd`` wants notifications for.
     if s.fds[fd].events != events:
-      var event = createEventStruct(events, fd)
+      if events == {}:
+        # This fd is idle -- it should not be registered to epoll.
+        # But it should remain a part of this selector instance.
+        # This is to prevent epoll_wait from returning immediately
+        # because its got fds which are waiting for no events and
+        # are therefore constantly ready. (leading to 100% CPU usage).
+        if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, fd, nil) != 0:
+          OSError(OSLastError())
+        s.fds[fd].events = events
+      else:
+        var event = createEventStruct(events, fd)
+        if s.fds[fd].events == {}:
+          # This fd is idle. It's not a member of this epoll instance and must
+          # be re-registered.
+          if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, fd, addr(event)) != 0:
+            OSError(OSLastError())
+        else:
+          if epoll_ctl(s.epollFD, EPOLL_CTL_MOD, fd, addr(event)) != 0:
+            OSError(OSLastError())
+        s.fds[fd].events = events
       
-      s.fds[fd].events = events
-      if epoll_ctl(s.epollFD, EPOLL_CTL_MOD, fd, addr(event)) != 0:
-        OSError(OSLastError())
       result = s.fds[fd]
   
   proc unregister*(s: PSelector, fd: TSocketHandle): PSelectorKey {.discardable.} =
@@ -123,7 +140,10 @@ when defined(linux) or defined(nimdoc):
     ## Determines whether selector contains a file descriptor.
     if s.fds.hasKey(fd):
       # Ensure the underlying epoll instance still contains this fd.
-      result = epollHasFd(s, fd)
+      if s.fds[fd].events != {}:
+        result = epollHasFd(s, fd)
+      else:
+        result = true
     else:
       return false