Commit 0aed1c6b authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 24da710f
...@@ -70,8 +70,6 @@ using std::vector; ...@@ -70,8 +70,6 @@ using std::vector;
// wcfs:: // wcfs::
namespace wcfs { namespace wcfs {
static string h(uint64_t v); // v -> 016x hex representation
#define h_(v) (h(v).c_str())
static error mmap_zero_into_ro(void *addr, size_t size); static error mmap_zero_into_ro(void *addr, size_t size);
static tuple<uint8_t*, error> mmap_ro(os::File f, off_t offset, size_t size); static tuple<uint8_t*, error> mmap_ro(os::File f, off_t offset, size_t size);
static error mmap_into_ro(void *addr, size_t size, os::File f, off_t offset); static error mmap_into_ro(void *addr, size_t size, os::File f, off_t offset);
...@@ -105,6 +103,8 @@ pair<Conn, error> WCFS::connect(zodb::Tid at) { ...@@ -105,6 +103,8 @@ pair<Conn, error> WCFS::connect(zodb::Tid at) {
} }
// close releases resources associated with wconn. // close releases resources associated with wconn.
//
// opened fileh and mappings become invalid to use.
// XXX what happens to file mmappings? // XXX what happens to file mmappings?
error _Conn::close() { error _Conn::close() {
_Conn& wconn = *this; _Conn& wconn = *this;
...@@ -135,7 +135,7 @@ error _Conn::close() { ...@@ -135,7 +135,7 @@ error _Conn::close() {
for (auto _ : wconn._filehtab) { for (auto _ : wconn._filehtab) {
auto f = _.second; auto f = _.second;
err = f->_headf->close(); err = f->_headf->close(); // XXX better -> fileh.close()? or deadlock on ._filehmu ?
if (err != nil) if (err != nil)
reterr1(err); reterr1(err);
f->_headf = nil; f->_headf = nil;
...@@ -145,9 +145,9 @@ error _Conn::close() { ...@@ -145,9 +145,9 @@ error _Conn::close() {
wconn._filehtab.clear(); wconn._filehtab.clear();
// XXX -> try to top // XXX -> try to xerr.Contextf at top
if (eret != nil) if (eret != nil)
eret = fmt::errorf("close conn @%s: %s", h_(wconn.at), v(eret)); eret = fmt::errorf("close conn @%s: %s", v(wconn.at), v(eret));
return eret; return eret;
} }
...@@ -220,7 +220,7 @@ error _Conn::__pin1(PinReq *req) { ...@@ -220,7 +220,7 @@ error _Conn::__pin1(PinReq *req) {
if (!(mmap->blk_start <= req->blk && req->blk < mmap->blk_stop())) if (!(mmap->blk_start <= req->blk && req->blk < mmap->blk_stop()))
continue; // blk ∉ mmap continue; // blk ∉ mmap
//trace("\tremmapblk %d @%s" % (req->blk, (h(req.at) if req.at else "head"))) //trace("\tremmapblk %d @%s" % (req->blk, (v(req.at) if req.at else "head")))
// pin only if virtmem did not dirtied page corresponding to this block already // pin only if virtmem did not dirtied page corresponding to this block already
// if virtmem dirtied the page - it will ask us to remmap it again after commit or abort. // if virtmem dirtied the page - it will ask us to remmap it again after commit or abort.
...@@ -279,7 +279,7 @@ pair<FileH, error> _Conn::open(zodb::Oid foid) { ...@@ -279,7 +279,7 @@ pair<FileH, error> _Conn::open(zodb::Oid foid) {
f->wconn = newref(&wconn); // XXX newref -> simpler? f->wconn = newref(&wconn); // XXX newref -> simpler?
f->foid = foid; f->foid = foid;
tie(f->_headf, err) tie(f->_headf, err)
= wconn._wc->_open(fmt::sprintf("head/bigfile/%s", h_(foid))); = wconn._wc->_open(fmt::sprintf("head/bigfile/%s", v(foid)));
if (err != nil) if (err != nil)
return make_pair(nil, err); return make_pair(nil, err);
...@@ -296,24 +296,27 @@ pair<FileH, error> _Conn::open(zodb::Oid foid) { ...@@ -296,24 +296,27 @@ pair<FileH, error> _Conn::open(zodb::Oid foid) {
// start watching f // start watching f
string ack; string ack;
tie(ack, err) = wconn._wlink->sendReq(context::background(), fmt::sprintf("watch %s @%s", h_(foid), h_(wconn.at))); tie(ack, err) = wconn._wlink->sendReq(context::background(), fmt::sprintf("watch %s @%s", v(foid), v(wconn.at)));
if (err != nil) if (err != nil)
return make_pair(nil, err); return make_pair(nil, err);
if (ack != "ok") { if (ack != "ok") {
// XXX unregister f from _filehtab // XXX unregister f from _filehtab
// XXX vvv -> errctx? // XXX vvv -> errctx?
return make_pair(nil, fmt::errorf("@%s: open f<%s>: watch: %s", h_(wconn.at), h_(foid), ack.c_str())); return make_pair(nil, fmt::errorf("@%s: open f<%s>: watch: %s", v(wconn.at), v(foid), ack.c_str()));
} }
return make_pair(f, nil); return make_pair(f, nil);
} }
// close releases resources associated with FileH. // close releases resources associated with FileH.
// XXX what happens with mappings? //
// Left fileh mappings become invalid to use.
error _FileH::close() { error _FileH::close() {
_FileH& fileh = *this; _FileH& fileh = *this;
// XXX err ctx // XXX err ctx
// XXX remove fileh from .wconn._filehtab ?
return fileh._headf->close(); return fileh._headf->close();
} }
...@@ -405,7 +408,7 @@ error _Conn::resync(zodb::Tid at) { ...@@ -405,7 +408,7 @@ error _Conn::resync(zodb::Tid at) {
return fmt::errorf("wcfs bug: head/file size %% blksize != 0"); return fmt::errorf("wcfs bug: head/file size %% blksize != 0");
for (auto mmap : f->_mmaps) { for (auto mmap : f->_mmaps) {
printf(" resync -> %s: unzero [%lu:%lu)", h_(at), f->_headfsize/f->blksize, headfsize/f->blksize); printf(" resync -> %s: unzero [%lu:%lu)", v(at), f->_headfsize/f->blksize, headfsize/f->blksize);
uint8_t *mem_unzero_start = min(mmap->mem_stop, uint8_t *mem_unzero_start = min(mmap->mem_stop,
mmap->mem_start + (f->_headfsize - mmap->blk_start*f->blksize)); mmap->mem_start + (f->_headfsize - mmap->blk_start*f->blksize));
uint8_t *mem_unzero_stop = min(mmap->mem_stop, uint8_t *mem_unzero_stop = min(mmap->mem_stop,
...@@ -422,13 +425,13 @@ error _Conn::resync(zodb::Tid at) { ...@@ -422,13 +425,13 @@ error _Conn::resync(zodb::Tid at) {
string ack; string ack;
tie(ack, err) = wconn._wlink->sendReq(context::background(), fmt::sprintf("watch %s @%s", h_(foid), h_(at))); tie(ack, err) = wconn._wlink->sendReq(context::background(), fmt::sprintf("watch %s @%s", v(foid), v(at)));
if (err != nil) if (err != nil)
return err; return err;
if (ack != "ok") { if (ack != "ok") {
// XXX unregister f from _filehtab // XXX unregister f from _filehtab
// XXX vvv -> errctx? // XXX vvv -> errctx?
return fmt::errorf("resync @%s -> @%s: f<%s>: %s", h_(wconn.at), h_(at), h_(foid), ack.c_str()); return fmt::errorf("resync @%s -> @%s: f<%s>: %s", v(wconn.at), v(at), v(foid), ack.c_str());
} }
} }
...@@ -457,7 +460,7 @@ error _Mapping::_remmapblk(int64_t blk, zodb::Tid at) { ...@@ -457,7 +460,7 @@ error _Mapping::_remmapblk(int64_t blk, zodb::Tid at) {
else { else {
// TODO share @rev fd until wconn is resynced? // TODO share @rev fd until wconn is resynced?
tie(fsfile, err) = f->wconn->_wc->_open( tie(fsfile, err) = f->wconn->_wc->_open(
fmt::sprintf("@%s/bigfile/%s", h_(at), h_(f->foid))); fmt::sprintf("@%s/bigfile/%s", v(at), v(f->foid)));
if (err != nil) if (err != nil)
return err; return err;
fclose = true; fclose = true;
...@@ -552,10 +555,6 @@ tuple<os::File, error> WCFS::_open(const string &path, int flags) { ...@@ -552,10 +555,6 @@ tuple<os::File, error> WCFS::_open(const string &path, int flags) {
// ---- misc ---- // ---- misc ----
static string h(uint64_t v) {
return fmt::sprintf("%016lx", v);
}
// mmap_zero_into_ro mmaps read-only zeros into [addr +size) so that region as all zeros. // mmap_zero_into_ro mmaps read-only zeros into [addr +size) so that region as all zeros.
// created mapping, even after it is accessed, does not consume memory. // created mapping, even after it is accessed, does not consume memory.
static error _mmap_zero_into_ro(void *addr, size_t size); static error _mmap_zero_into_ro(void *addr, size_t size);
......
...@@ -219,3 +219,44 @@ tuple<uint64_t, error> parseUint(const string& s) { ...@@ -219,3 +219,44 @@ tuple<uint64_t, error> parseUint(const string& s) {
} }
} // xstrconv:: } // xstrconv::
// xerr::
namespace xerr {
Contextf::Contextf(const char *format, ...) {
Contextf& c = *this;
va_list argp;
va_start(argp, format);
c.errctx = fmt::vsprintf(format, argp);
va_end(argp);
}
error Contextf::operator() (error err) {
Contextf& c = *this;
if (err == nil)
return nil;
return fmt::errorf("%s: %s", c.errctx.c_str(), v(err));
}
} // xerr::
// wcfs::
namespace wcfs {
template<> string v_(error err) {
return (err != nil) ? err->Error() : "nil";
}
static string h016(uint64_t v) { return fmt::sprintf("%016lx", v); }
template<> string v_(zodb::Tid tid) { return h016(tid); }
//template<> string v_(zodb::Oid oid) { return h016(oid); }
// XXX Tid and Oid are typedefs for uint64_t and C++ reduces template
// specializations to theunderlying type. This providing specialization for
// both Tid and Oid results in "multiple definition" error.
} // wcfs::
...@@ -150,6 +150,31 @@ typedef uint64_t Oid; ...@@ -150,6 +150,31 @@ typedef uint64_t Oid;
} // zodb:: } // zodb::
// xerr::
namespace xerr {
// xerr::Contextf mimics xerr.Contextf from Go.
//
// Usage is a bit different(*) compared to Go:
//
// func dosSomething(arg) {
// xerr.Contextf E("doing something %s", v(arg));
// ...
// return E(err);
// }
//
// (*) because C++ does not allow to modify returned value on the fly.
class Contextf {
string errctx;
public:
Contextf(const char *format, ...);
error operator() (error);
};
}
// wcfs:: // wcfs::
namespace wcfs { namespace wcfs {
...@@ -159,8 +184,8 @@ const zodb::Tid TidHead = -1ULL; ...@@ -159,8 +184,8 @@ const zodb::Tid TidHead = -1ULL;
// v mimics %v for T to be used in printf & friends. // v mimics %v for T to be used in printf & friends.
// //
// NOTE returned char* pointer is guaranteed to stay valid till end of current expression. // NOTE returned char* pointer is guaranteed to stay valid only till end of
// e.g. // current expression. For example
// //
// printf("hello %s", v(obj)) // printf("hello %s", v(obj))
// //
...@@ -170,22 +195,14 @@ const zodb::Tid TidHead = -1ULL; ...@@ -170,22 +195,14 @@ const zodb::Tid TidHead = -1ULL;
// use(x); // use(x);
// //
// is not valid. // is not valid.
#define v(obj) (v_(obj).c_str()) #define v(obj) (wcfs::v_(obj).c_str())
template<typename T> string v_(T obj) { template<typename T> string v_(T obj) {
return obj.String(); return obj.String();
} }
template<> inline string v_(error err) { template<> string v_(error);
return (err != nil) ? err->Error() : "nil"; template<> string v_(zodb::Tid);
} template<> string v_(zodb::Oid);
#if 0
const char *v(error err) {
if (err != nil)
return err->Error().c_str(); // XXX Error() gives temp. obj
return "nil";
}
#endif
} // wcfs:: } // wcfs::
......
...@@ -89,7 +89,7 @@ error _WatchLink::closeWrite() { ...@@ -89,7 +89,7 @@ error _WatchLink::closeWrite() {
// close closes the link. // close closes the link.
error _WatchLink::close() { error _WatchLink::close() {
_WatchLink& wlink = *this; _WatchLink& wlink = *this;
// XXX errctx? xerr::Contextf E("wlink close"); // XXX + wlink ID? + wcfs ID
error err = wlink.closeWrite(); error err = wlink.closeWrite();
wlink._serveCancel(); wlink._serveCancel();
...@@ -110,7 +110,9 @@ error _WatchLink::close() { ...@@ -110,7 +110,9 @@ error _WatchLink::close() {
if (err == nil) if (err == nil)
err = err3; err = err3;
return err; //return errctx(err);
//return E(errctx, err);
return E(err);
} }
// _serveRX receives messages from ._f and dispatches them according to streamID. // _serveRX receives messages from ._f and dispatches them according to streamID.
......
...@@ -1819,6 +1819,8 @@ def test_wcfs_virtmem(): ...@@ -1819,6 +1819,8 @@ def test_wcfs_virtmem():
# XXX w mapping with RW - in sync # XXX w mapping with RW - in sync
# XXX fh close then open again and use
# ---- misc --- # ---- misc ---
......
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