Commit a035b1cd authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent a252e8ca
......@@ -102,7 +102,7 @@ typedef refptr<struct _Conn> Conn;
struct _Conn : object {
WCFS *_wc;
zodb::Tid at;
WatchLink _wlink; // watch/receive pins for created mappings
WatchLink _wlink; // watch/receive pins for mappings created under this conn
sync::Mutex _filehmu;
dict<zodb::Oid, FileH> _filehtab; // {} foid -> fileh
......@@ -131,8 +131,9 @@ private:
// FileH represent isolated file view under Conn.
//
// The file view is maintained to be as of @Conn.at database state.
// The file view uses /head/<file>/data primarilty and @revX/<file>/data pin overrides.
// The file view is maintained to be as of @Conn.at database state even in the
// presence of simultaneous database changes. The file view uses
// /head/<file>/data primarily and @revX/<file>/data pin overrides.
//
// Use .mmap to map file view into memory.
typedef refptr<struct _FileH> FileH;
......
......@@ -1720,21 +1720,30 @@ class tMapping(object):
dataok += b'\0'*(fh.blksize - len(dataok)) # trailing zeros
blkview = t.mmap.mem[blk_inmmap*fh.blksize:][:fh.blksize]
# XXX first access without GIL, so that e.g. if there is timeout on
# wcfs.py side, _abort_ontimeout could run and kill WCFS.
# FIXME also test with GIL locked, since wcfs.py pinner must be itself
# running without GIL. XXX
#_ = read_nogil(blkview[:1])
_ = blkview[0] # NOTE with gil
# NOTE access to memory goes _with_ GIL: this verifies that wcfs pinner
# is implemented in fully nogil mode because if that was not the case,
# the pinner would deadlock trying to acquire GIL in its thread while
# user thread that triggered the access is already holding the GIL.
#
# - - - - - -
# | |
# pinner <------.
# | | wcfs
# client -------^
# | |
# - - - - - -
# client process
#
_ = blkview[0]
assert _ == dataok[0]
assert blkview.tobytes() == dataok
# XXX assertData
# test_wcfspy_virtmem verifies wcfs.py integration with virtmem.
# test_wcfs_virtmem unit-tests virtmem layer of wcfs client.
@func
def test_wcfspy_virtmem():
def test_wcfs_virtmem():
t = tDB(); zf = t.zfile
defer(t.close)
......@@ -1746,6 +1755,13 @@ def test_wcfspy_virtmem():
fh = wconn.open(zf._p_oid)
defer(fh.close)
# pinned(fh) returns fh.pinned with rev wrapped into tAt.
# XXX better wrap FileH into tFileH and do this automatically in .pinned ?
def pinned(fh):
p = fh.pinned.copy()
for blk in p:
p[blk] = tAt(t, p[blk])
return p
# create mmap with 1 block beyond file size
m1 = fh.mmap(2, 3)
......@@ -1757,14 +1773,6 @@ def test_wcfspy_virtmem():
tm1 = tMapping(m1)
# pinned returns fh.pinned with rev wrapped into tAt.
# XXX better wrap FileH into tFileH and do this automatically in .pinned ?
def pinned(fh):
p = fh.pinned.copy()
for blk in p:
p[blk] = tAt(t, p[blk])
return p
#assertCache(m1, [0,0,0])
assert pinned(fh) == {}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment