nim-datastore/datastore/threads/foreignbuffer.nim

77 lines
1.9 KiB
Nim
Raw Normal View History

2023-09-08 15:09:15 -06:00
2023-09-11 14:48:53 -06:00
import std/locks
2023-09-08 15:09:15 -06:00
type
2023-09-11 14:48:53 -06:00
## Pass foreign buffers between threads.
2023-09-08 15:09:15 -06:00
##
2023-09-11 14:48:53 -06:00
## This is meant to be used as temporary holder
2023-09-08 15:09:15 -06:00
## pointer to a foreign buffer that is being passed
## between threads.
##
## The receiving thread should copy the contained buffer
## to it's local GC as soon as possible. Should only be
## used with refgc.
##
ForeignBuff*[T] = object
2023-09-11 14:48:53 -06:00
lock: Lock
2023-09-08 15:09:15 -06:00
buf: ptr UncheckedArray[T]
len: int
cell: ForeignCell
2023-09-11 14:48:53 -06:00
proc `=sink`[T](self: var ForeignBuff[T], b: ForeignBuff[T]) =
withLock(self.lock):
`=destroy`(self)
wasMoved(self)
self.len = b.len
self.buf = b.buf
self.cell = b.cell
2023-09-08 15:09:15 -06:00
2023-09-11 14:48:53 -06:00
proc `=copy`[T](self: var ForeignBuff[T], b: ForeignBuff[T]) {.error.}
2023-09-08 15:09:15 -06:00
proc `=destroy`[T](self: var ForeignBuff[T]) =
2023-09-11 14:48:53 -06:00
withLock(self.lock):
if self.cell.data != nil:
echo "DESTROYING CELL"
dispose self.cell
2023-09-08 15:09:15 -06:00
proc len*[T](self: ForeignBuff[T]): int =
return self.len
proc get*[T](self: ForeignBuff[T]): ptr UncheckedArray[T] =
self.buf
proc attach*[T](
self: var ForeignBuff[T],
2023-09-11 14:48:53 -06:00
buf: openArray[T]) =
## Attach self foreign pointer to this buffer
2023-09-08 15:09:15 -06:00
##
2023-09-11 14:48:53 -06:00
withLock(self.lock):
self.buf = makeUncheckedArray[T](baseAddr buf)
self.len = buf.len
self.cell = protect(self.buf)
2023-09-08 15:09:15 -06:00
2023-09-11 14:48:53 -06:00
func attached*[T]() =
## Check if self foreign pointer is attached to this buffer
##
withLock(self.lock):
return self.but != nil and self.cell.data != nil
## NOTE: Converters might return copies of the buffer,
## this should be overall safe since we want to copy
## the buffer local GC anyway.
converter toSeq*[T](self: ForeignBuff[T]): seq[T] | lent seq[T] =
@(self.buf.toOpenArray(0, self.len - 1))
converter toString*[T](self: ForeignBuff[T]): string | lent string =
$(self.buf.toOpenArray(0, self.len - 1))
converter getVal*[T](self: ForeignBuff[T]): ptr UncheckedArray[T] =
self.buf
2023-09-08 15:09:15 -06:00
func init*[T](_: type ForeignBuff[T]): ForeignBuff[T] =
2023-09-11 14:48:53 -06:00
var
lock = Lock()
lock.initLock()
ForeignBuff[T](lock: lock)