diff options
author | Araq <rumpf_a@web.de> | 2011-07-08 01:29:15 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2011-07-08 01:29:15 +0200 |
commit | 99bcc233cd8fb3bb9b6f3f0857e477dd9b33c9e8 (patch) | |
tree | 2259a14b53ec4fc6f8dedc311eb5e6b837f44180 /lib/pure | |
parent | 170573a87f0df749bdb91126c930826ba5329e95 (diff) | |
download | Nim-99bcc233cd8fb3bb9b6f3f0857e477dd9b33c9e8.tar.gz |
bugfix: 'set' overloadable; further steps for multi threading support
Diffstat (limited to 'lib/pure')
-rw-r--r-- | lib/pure/collections/queues.nim | 89 | ||||
-rwxr-xr-x | lib/pure/marshal.nim | 33 | ||||
-rwxr-xr-x | lib/pure/osproc.nim | 22 |
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) |