diff options
author | Araq <rumpf_a@web.de> | 2011-07-09 01:18:33 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2011-07-09 01:18:33 +0200 |
commit | 2565ff8ddec9fcf43fbda2fae6f04806c1bc6e8a (patch) | |
tree | 8ab9b57efd41ac133eaf29b0a751d42cce1f66df /lib/system/inboxes.nim | |
parent | 99bcc233cd8fb3bb9b6f3f0857e477dd9b33c9e8 (diff) | |
download | Nim-2565ff8ddec9fcf43fbda2fae6f04806c1bc6e8a.tar.gz |
basic message passing working
Diffstat (limited to 'lib/system/inboxes.nim')
-rw-r--r-- | lib/system/inboxes.nim | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/lib/system/inboxes.nim b/lib/system/inboxes.nim index 8f683f612..1f5d56c16 100644 --- a/lib/system/inboxes.nim +++ b/lib/system/inboxes.nim @@ -22,6 +22,8 @@ type PInbox = ptr TInbox TLoadStoreMode = enum mStore, mLoad +const ThreadDeadMask = -2 + proc initInbox(p: pointer) = var inbox = cast[PInbox](p) initSysLock(inbox.lock) @@ -30,6 +32,9 @@ proc initInbox(p: pointer) = proc freeInbox(p: pointer) = var inbox = cast[PInbox](p) + # we need to grab the lock to be save against sending threads! + acquireSys(inbox.lock) + inbox.mask = ThreadDeadMask deallocOsPages(inbox.region) deinitSys(inbox.lock) deinitSysCond(inbox.cond) @@ -158,7 +163,6 @@ proc rawSend(q: PInbox, data: pointer, typ: PNimType) = q.mask = cap*2 - 1 q.wr = q.count q.rd = 0 - #echo "came here" storeAux(addr(q.data[q.wr * typ.size]), data, typ, q, mStore) inc q.count q.wr = (q.wr + 1) and q.mask @@ -177,23 +181,34 @@ template lockInbox(q: expr, action: stmt) = proc send*[TMsg](receiver: var TThread[TMsg], msg: TMsg) = ## sends a message to a thread. `msg` is deeply copied. var q = cast[PInbox](getInBoxMem(receiver)) + if q.mask == ThreadDeadMask: + raise newException(EDeadThread, "cannot send message; thread died") acquireSys(q.lock) var m: TMsg shallowCopy(m, msg) - rawSend(q, addr(m), cast[PNimType](getTypeInfo(msg))) + var typ = cast[PNimType](getTypeInfo(msg)) + rawSend(q, addr(m), typ) + q.elemType = typ releaseSys(q.lock) SignalSysCond(q.cond) -proc recv*[TMsg](): TMsg = - ## receives a message from its internal message queue. This blocks until - ## a message has arrived! You may use ``peek`` to avoid the blocking. +proc llRecv(res: pointer, typ: PNimType) = + # to save space, the generic is as small as possible var q = cast[PInbox](getInBoxMem()) acquireSys(q.lock) while q.count <= 0: WaitSysCond(q.cond, q.lock) - rawRecv(q, addr(result), cast[PNimType](getTypeInfo(result))) + if typ != q.elemType: + releaseSys(q.lock) + raise newException(EInvalidValue, "cannot receive message of wrong type") + rawRecv(q, res, typ) releaseSys(q.lock) +proc recv*[TMsg](): TMsg = + ## receives a message from its internal message queue. This blocks until + ## a message has arrived! You may use ``peek`` to avoid the blocking. + llRecv(addr(result), cast[PNimType](getTypeInfo(result))) + proc peek*(): int = ## returns the current number of messages in the inbox. var q = cast[PInbox](getInBoxMem()) |