summary refs log tree commit diff stats
path: root/lib/pure
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2011-07-08 01:29:15 +0200
committerAraq <rumpf_a@web.de>2011-07-08 01:29:15 +0200
commit99bcc233cd8fb3bb9b6f3f0857e477dd9b33c9e8 (patch)
tree2259a14b53ec4fc6f8dedc311eb5e6b837f44180 /lib/pure
parent170573a87f0df749bdb91126c930826ba5329e95 (diff)
downloadNim-99bcc233cd8fb3bb9b6f3f0857e477dd9b33c9e8.tar.gz
bugfix: 'set' overloadable; further steps for multi threading support
Diffstat (limited to 'lib/pure')
-rw-r--r--lib/pure/collections/queues.nim89
-rwxr-xr-xlib/pure/marshal.nim33
-rwxr-xr-xlib/pure/osproc.nim22
3 files changed, 142 insertions, 2 deletions
diff --git a/lib/pure/collections/queues.nim b/lib/pure/collections/queues.nim
new file mode 100644
index 000000000..2130d9949
--- /dev/null
+++ b/lib/pure/collections/queues.nim
@@ -0,0 +1,89 @@
+#
+#
+#            Nimrod's Runtime Library
+#        (c) Copyright 2011 Andreas Rumpf
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+## Implementation of a queue. The underlying implementation uses a ``seq``.
+
+import math
+
+type
+  TQueue* {.pure, final.}[T] = object ## a queue
+    data: seq[T]
+    rd, wr, count, mask: int
+    
+proc initQueue*[T](initialSize=4): TQueue[T] =
+  ## creates a new queue. `initialSize` needs to be a power of 2.
+  assert IsPowerOfTwo(initialSize)
+  result.mask = initialSize-1
+  newSeq(result.data, initialSize)
+
+proc len*[T](q: TQueue[T]): int =
+  ## returns the number of elements of `q`.
+  result = q.count
+
+iterator items*[T](q: TQueue[T]): T =
+  ## yields every element of `q`.
+  var i = q.rd
+  var c = q.count
+  while c > 0:
+    dec c
+    yield q.data[i]
+    i = (i + 1) and q.mask
+
+proc add*[T](q: var TQueue[T], item: T) =
+  ## adds an `item` to the end of the queue `q`.
+  var cap = q.mask+1
+  if q.count >= cap:
+    var n: seq[T]
+    newSeq(n, cap*2)
+    var i = 0
+    for x in items(q):
+      shallowCopy(n[i], x)
+      inc i
+    shallowCopy(q.data, n)
+    q.mask = cap*2 - 1
+    q.wr = q.count
+    q.rd = 0
+  inc q.count
+  q.data[q.wr] = item
+  q.wr = (q.wr + 1) and q.mask
+
+proc enqueue*[T](q: var TQueue[T], item: T) =
+  ## alias for the ``add`` operation.
+  add(q, item)
+
+proc dequeue*[T](q: var TQueue[T]): T =
+  ## removes and returns the first element of the queue `q`.
+  assert q.count > 0
+  dec q.count
+  result = q.data[q.rd]
+  q.rd = (q.rd + 1) and q.mask
+
+proc `$`*[T](q: TQueue[T]): string = 
+  ## turns a queue into its string representation.
+  result = "["
+  for x in items(q):
+    if result.len > 1: result.add(", ")
+    result.add($x)
+  result.add("]")
+
+when isMainModule:
+  var q = initQueue[int]()
+  q.add(123)
+  q.add(9)
+  q.add(4)
+  var first = q.dequeue
+  q.add(56)
+  q.add(6)
+  var second = q.dequeue
+  q.add(789)
+  
+  assert first == 123
+  assert second == 9
+  assert($q == "[4, 56, 6, 789]")
+
diff --git a/lib/pure/marshal.nim b/lib/pure/marshal.nim
index f96d177ae..354d70a71 100755
--- a/lib/pure/marshal.nim
+++ b/lib/pure/marshal.nim
@@ -8,7 +8,26 @@
 #

 

 ## This module contains procs for serialization and deseralization of 

-## arbitrary Nimrod data structures. The serialization format uses JSON.

+## arbitrary Nimrod data structures. The serialization format uses JSON.
+##
+## **Restriction**: For objects their type is **not** serialized. This means
+## essentially that it does not work if the object has some other runtime
+## type than its compiletime type:
+##
+## .. code-block:: nimrod
+## 
+##   type 
+##     TA = object
+##     TB = object of TA
+##       f: int
+##
+##   var
+##     a: ref TA
+##     b: ref TB
+##
+##   new(b)
+##   a = b
+##   echo($$a[]) # produces "{}", not "{f: 0}"

 

 import streams, typeinfo, json, intsets, tables

 

@@ -286,3 +305,15 @@ when isMainModule:
   echo($$test7)
   testit(test7)
 
+  type 
+    TA = object
+    TB = object of TA
+      f: int
+
+  var
+    a: ref TA
+    b: ref TB
+  new(b)
+  a = b
+  echo($$a[]) # produces "{}", not "{f: 0}"

+
diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim
index 60bef813d..2b7047143 100755
--- a/lib/pure/osproc.nim
+++ b/lib/pure/osproc.nim
@@ -77,11 +77,14 @@ proc startProcess*(command: string,
   ## If ``env == nil`` the environment is inherited of
   ## the parent process. `options` are additional flags that may be passed
   ## to `startProcess`. See the documentation of ``TProcessOption`` for the
-  ## meaning of these flags.
+  ## meaning of these flags. You need to `close` the process when done.
   ##
   ## Return value: The newly created process object. Nil is never returned,
   ## but ``EOS`` is raised in case of an error.
 
+proc close*(p: PProcess) {.rtl, extern: "nosp$1".}
+  ## When the process has finished executing, cleanup related handles
+
 proc suspend*(p: PProcess) {.rtl, extern: "nosp$1".}
   ## Suspends the process `p`.
 
@@ -179,6 +182,7 @@ proc execProcesses*(cmds: openArray[string],
             err.add("\n")
           echo(err)
         result = max(waitForExit(q[r]), result)
+        if q[r] != nil: close(q[r])
         q[r] = startProcessAux(cmds[i], options=options)
         r = (r + 1) mod n
     else:
@@ -189,15 +193,18 @@ proc execProcesses*(cmds: openArray[string],
           if not running(q[r]):
             #echo(outputStream(q[r]).readLine())
             result = max(waitForExit(q[r]), result)
+            if q[r] != nil: close(q[r])
             q[r] = startProcessAux(cmds[i], options=options)
             inc(i)
             if i > high(cmds): break
     for i in 0..m-1:
+      if q[i] != nil: close(q[i])
       result = max(waitForExit(q[i]), result)
   else:
     for i in 0..high(cmds):
       var p = startProcessAux(cmds[i], options=options)
       result = max(waitForExit(p), result)
+      close(p)
 
 proc select*(readfds: var seq[PProcess], timeout = 500): int
   ## `select` with a sensible Nimrod interface. `timeout` is in miliseconds.
@@ -215,6 +222,8 @@ when not defined(useNimRtl):
     while running(p) or not outp.atEnd(outp):
       result.add(outp.readLine())
       result.add("\n")
+    outp.close(outp)
+    close(p)
 
 when false:
   proc deallocCStringArray(a: cstringArray) =
@@ -356,6 +365,12 @@ when defined(Windows) and not defined(useNimRtl):
     result.FProcessHandle = procInfo.hProcess
     result.id = procInfo.dwProcessID
 
+  proc close(p: PProcess) =
+    discard CloseHandle(p.inputHandle)
+    discard CloseHandle(p.outputHandle)
+    discard CloseHandle(p.errorHandle)
+    discard CloseHandle(p.FProcessHandle)
+
   proc suspend(p: PProcess) =
     discard SuspendThread(p.FProcessHandle)
 
@@ -523,6 +538,11 @@ elif not defined(useNimRtl):
     discard close(p_stdin[readIdx])
     discard close(p_stdout[writeIdx])
 
+  proc close(p: PProcess) =
+    discard close(p.inputHandle)
+    discard close(p.outputHandle)
+    discard close(p.errorHandle)
+
   proc suspend(p: PProcess) =
     discard kill(p.id, SIGSTOP)