Commit 25c978bc authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent f21a2d91
...@@ -112,7 +112,7 @@ cdef class PyWCFS: ...@@ -112,7 +112,7 @@ cdef class PyWCFS:
def connect(PyWCFS pywc, pyat): # -> PyConn def connect(PyWCFS pywc, pyat): # -> PyConn
cdef Tid at = u64(pyat) cdef Tid at = u64(pyat)
with nogil: with nogil:
_ = pywc.wc.connect(at) _ = wcfs_connect_pyexc(&pywc.wc, at)
wconn = _.first wconn = _.first
err = _.second err = _.second
...@@ -264,6 +264,9 @@ cdef nogil: ...@@ -264,6 +264,9 @@ cdef nogil:
pair[WatchLink, error] wcfs_openwatch_pyexc(WCFS *wcfs) except +topyexc: pair[WatchLink, error] wcfs_openwatch_pyexc(WCFS *wcfs) except +topyexc:
return wcfs._openwatch() return wcfs._openwatch()
pair[Conn, error] wcfs_connect_pyexc(WCFS *wcfs, Tid at) except +topyexc:
return wcfs.connect(at)
error wlink_close_pyexc(WatchLink wlink) except +topyexc: error wlink_close_pyexc(WatchLink wlink) except +topyexc:
return wlink.close() return wlink.close()
......
...@@ -41,6 +41,7 @@ using std::pair; ...@@ -41,6 +41,7 @@ using std::pair;
#include "wcfs_misc.h" #include "wcfs_misc.h"
struct _File; struct _File;
struct _Mapping;
struct PinReq; struct PinReq;
typedef refptr<class _Conn> Conn; typedef refptr<class _Conn> Conn;
typedef refptr<class _WatchLink> WatchLink; typedef refptr<class _WatchLink> WatchLink;
...@@ -91,6 +92,7 @@ public: ...@@ -91,6 +92,7 @@ public:
public: public:
error close(); error close();
_Mapping* mmap(zodb::Oid foid, int64_t blk_start, int64_t blk_len);
error resync(zodb::Tid at); error resync(zodb::Tid at);
private: private:
......
...@@ -50,8 +50,6 @@ static string h(uint64_t v); // v -> 016x hex representation ...@@ -50,8 +50,6 @@ static string h(uint64_t v); // v -> 016x hex representation
static error mmap_zero_into_ro(void *addr, size_t size); static error mmap_zero_into_ro(void *addr, size_t size);
static error mmap_into_ro(void *addr, size_t size, const os::File &f, off_t offset); static error mmap_into_ro(void *addr, size_t size, const os::File &f, off_t offset);
struct _Mapping;
// _File represent isolated file view under Conn. // _File represent isolated file view under Conn.
// //
// XXX doc XXX naming -> _FileView ? // XXX doc XXX naming -> _FileView ?
...@@ -71,7 +69,7 @@ struct _File { ...@@ -71,7 +69,7 @@ struct _File {
// XXX -> refptr ? // XXX -> refptr ?
struct _Mapping { struct _Mapping {
_File *file; _File *file;
int blk_start; // offset of this mapping in file int64_t blk_start; // offset of this mapping in file
BigFileH *fileh; // mmapped under this file handle BigFileH *fileh; // mmapped under this file handle
uint8_t *mem_start; // mmapped memory [mem_start, mem_stop) uint8_t *mem_start; // mmapped memory [mem_start, mem_stop)
...@@ -252,7 +250,88 @@ void _Conn::_pin1(PinReq *req) { ...@@ -252,7 +250,88 @@ void _Conn::_pin1(PinReq *req) {
wconn._filemu.unlock(); wconn._filemu.unlock();
} }
// XXX Conn::mmap // mmap creates file mapping representing file[blk_start +blk_len) data as of wconn.at database state.
_Mapping* _Conn::mmap(zodb::Oid foid, int64_t blk_start, int64_t blk_len) {
_Conn& wconn = *this;
// XXX err ctx
error err;
if (blk_start < 0)
panic("blk_start < 0");
if (blk_len < 0)
panic("blk_len < 0");
int64_t blk_stop = blk_start + blk_len; // XXX overflow
wconn._filemu.lock();
defer([&]() {
wconn._filemu.unlock();
});
_File* f; bool ok;
tie(f, ok) = wconn._filetab.get(foid);
if (f == nil) {
f = new _File();
f->wconn = newref(&wconn); // XXX newref -> simpler?
f->foid = foid;
tie(f->headf, err)
= wconn._wc->_open(fmt::sprintf("head/bigfile/%s", h_(foid)));
if (err != nil)
panic("TODO"); // XXX err
//f.pinned = {}
//f.mmaps = []
struct stat st;
err = f->headf->stat(&st);
if (err != nil)
panic("TODO"); // XXX
f->blksize = st.st_blksize;
f->headfsize = st.st_size;
if (!(f->headfsize % f->blksize == 0))
//return fmt::errorf("wcfs bug: head/file size %% blksize != 0");
panic("wcfs bug: head/file size %% blksize != 0"); // XXX -> err
wconn._filetab[foid] = f;
// start watching f
string ack;
tie(ack, err) = wconn._wlink->sendReq(context::background(), fmt::sprintf("watch %s @%s", h_(foid), h_(wconn.at)));
if (err != nil)
panic("TODO"); // XXX
if (ack != "ok") {
// XXX unregister f from _filetab
// XXX vvv -> errctx?
/*return XXX*/ fmt::errorf("@%s: mmap f<%s>[%d +%d): %s", h_(wconn.at), h_(foid), blk_start, blk_len, ack.c_str());
panic("TODO ack != ok"); // XXX ^^^
}
}
// XXX relock wconn -> f ?
// XXX reenable
return nil;
#if 0
// create memory with head/f mapping and applied pins
// mmap-in zeros after f.size (else access to memory after file.size will raise SIGBUS)
start = blk_start*f.blksize
mem = mm.map_ro(f.headf.fileno(), start, blk_len*f.blksize)
zmemtail = mem[max(f.headfsize, start) - start:]
if len(zmemtail) != 0:
mm.map_zero_into_ro(zmemtail)
mmap = _Mapping()
mmap.file = f
mmap.blk_start = blk_start
mmap.mem = mem
for blk, rev in f.pinned.items(): // XXX keep f.pinned ↑blk and use binary search?
if not (blk_start <= blk < blk_stop):
continue // blk out of this mapping
mmap._remmapblk(blk, rev)
f.mmaps.append(mmap) // XXX keep f.mmaps ↑blk_start
return mmap;
#endif
}
// resync resyncs connection and its mappings onto different database view. // resync resyncs connection and its mappings onto different database view.
error _Conn::resync(zodb::Tid at) { error _Conn::resync(zodb::Tid at) {
......
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