Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
W
wendelin.core
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Joshua
wendelin.core
Commits
2c2a094f
Commit
2c2a094f
authored
Mar 05, 2020
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
a288e2bc
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
122 additions
and
26 deletions
+122
-26
wcfs/client/wcfs.cpp
wcfs/client/wcfs.cpp
+63
-25
wcfs/client/wcfs.h
wcfs/client/wcfs.h
+1
-1
wcfs/client/wcfs_misc.cpp
wcfs/client/wcfs_misc.cpp
+46
-0
wcfs/client/wcfs_misc.h
wcfs/client/wcfs_misc.h
+12
-0
No files found.
wcfs/client/wcfs.cpp
View file @
2c2a094f
...
...
@@ -69,7 +69,7 @@
// never shrink. It is indeed currently so, but will have to be revisited
// if/when wendelin.core adds bigfile truncation. Wcfs client restats
// wcfs/head/f at every transaction boundary (Conn.resync) and remembers f.size
// in FileH._headfsize for use during one transaction.
// in FileH._headfsize for use during one transaction
(%)
.
//
//
// Integration with wendelin.core virtmem layer
...
...
@@ -111,6 +111,7 @@
// (+) currently, for simplicity, there is one pinner thread for each connection.
// In the future, for efficiency, it might be reworked to be one pinner thread
// that serves all connections simultaneously.
// (%) see _headWait comments on how this has to be reworked.
// Wcfs client locking organization
...
...
@@ -167,6 +168,7 @@
#include <golang/errors.h>
#include <golang/fmt.h>
#include <golang/io.h>
#include <golang/time.h>
#include <algorithm>
#include <string>
...
...
@@ -181,6 +183,8 @@ using std::min;
using
std
::
max
;
using
std
::
vector
;
namespace
ioutil
=
io
::
ioutil
;
#define TRACE 0
#if TRACE
...
...
@@ -204,13 +208,21 @@ static error mmap_into_ro(void *addr, size_t size, os::File f, off_t offset);
// connect creates new Conn viewing WCFS state as of @at.
pair
<
Conn
,
error
>
WCFS
::
connect
(
zodb
::
Tid
at
)
{
WCFS
*
wc
=
this
;
xerr
::
Contextf
E
(
"
wcfs %s: connect @%s"
,
v
(
wc
->
mountpoint
),
v
(
at
));
xerr
::
Contextf
E
(
"
%s: connect @%s"
,
v
(
wc
),
v
(
at
));
etrace
(
""
);
error
err
;
// TODO support !isolated mode
// need to wait till `wcfs/head/at ≥ at` because e.g. Conn.open stats
// head/f to get f.headfsize.
err
=
wc
->
_headWait
(
at
);
if
(
err
!=
nil
)
{
return
make_pair
(
nil
,
E
(
err
));
}
WatchLink
wlink
;
error
err
;
tie
(
wlink
,
err
)
=
wc
->
_openwatch
();
if
(
err
!=
nil
)
return
make_pair
(
nil
,
E
(
err
));
...
...
@@ -227,25 +239,52 @@ pair<Conn, error> WCFS::connect(zodb::Tid at) {
return
wconn
->
_pinner
(
ctx
);
});
// need to wait till `wcfs/head/at ≥ at` because e.g. Conn.open stats
// head/f to get f.headfsize.
// XXX atMu.RLock ?
err
=
wconn
->
_headWait
(
at
);
if
(
err
!=
nil
)
{
// XXX bring conn down - stop pinner
return
make_pair
(
nil
,
E
(
err
));
}
return
make_pair
(
wconn
,
nil
);
}
// _headWait waits till wcfs/head/at becomes ≥ at.
//
// XXX locks condition?
// XXX place?
error
_Conn
::
_headWait
(
zodb
::
Tid
at
)
{
// XXX +ctx ?
// FIXME implement
//
// _headWait is currently needed, because client stats wcfs/head/f to get f
// size assuming that f size only ↑. The assumption is not generally valid
// (e.g. f might be truncated = hole puched for block at tail), but holds true
// for now. However to get correct results wcfs/head/f has to be statt'ed
// _after_ wcfs view of the database becomes ≥ wconn.at.
//
// TODO extend isolation protocol to report f size as of @at database state at
// watch init/update(*). This way there won't be need for headWait as correct
// file size @at will be returned by wcfs itself, which will also work if
// wcfs/head/f size is changed arbitrarily.
//
// (*) equivalient might be to send something like "pin #<bsize>.. Z" (pin
// blocks bsize till ∞ to zeros).
error
WCFS
::
_headWait
(
zodb
::
Tid
at
)
{
WCFS
*
wc
=
this
;
xerr
::
Contextf
E
(
"%s: headWait @%s"
,
v
(
wc
),
v
(
at
));
etrace
(
""
);
zodb
::
Tid
xat
;
string
xatStr
;
error
err
;
// XXX dumb implementation, because _headWait should go away.
while
(
1
)
{
tie
(
xatStr
,
err
)
=
ioutil
::
ReadFile
(
wc
->
_path
(
"head/at"
));
if
(
err
!=
nil
)
return
E
(
err
);
tie
(
xat
,
err
)
=
xstrconv
::
parseHex64
(
xatStr
);
if
(
err
!=
nil
)
return
E
(
fmt
::
errorf
(
"head/at: %w"
,
err
));
if
(
xat
>=
at
)
break
;
time
::
sleep
(
1E-6
);
// XXX -> time::millisecond
}
return
nil
;
}
...
...
@@ -555,22 +594,21 @@ error _Conn::resync(zodb::Tid at) {
wconn
.
_atMu
.
RUnlock
();
etrace
(
""
);
// bring wconn + fileh + mmaps down on error
bool
retok
=
false
;
defer
([
&
]()
{
if
(
!
retok
)
wconn
.
close
();
// ignore error
});
// XXX _downErr -> E
// XXX at ^ (increases) -> rejected by wcfs XXX or also precheck here?
//
first
wait for wcfs/head to be >= at.
// wait for wcfs/head to be >= at.
// we need this e.g. to be sure that head/f.size is at least as big that it will be @at state.
err
=
wconn
.
_headWait
(
at
);
err
=
wconn
.
_
wc
->
_
headWait
(
at
);
if
(
err
!=
nil
)
return
err
;
return
E
(
err
)
;
// bring wconn + fileh + mmaps down on error
bool
retok
=
false
;
defer
([
&
]()
{
if
(
!
retok
)
wconn
.
close
();
// ignore error
});
// lock wconn._atMu.W . This excludes everything else, and in
// particular _pinner_, from running and mutating files and mappings.
...
...
wcfs/client/wcfs.h
View file @
2c2a094f
...
...
@@ -152,6 +152,7 @@ struct WCFS {
pair
<
WatchLink
,
error
>
_openwatch
();
string
String
()
const
;
error
_headWait
(
zodb
::
Tid
at
);
};
// Conn represents logical connection that provides view of data on wcfs
...
...
@@ -208,7 +209,6 @@ private:
error
__pinner
(
context
::
Context
ctx
);
error
_pin1
(
PinReq
*
req
);
error
__pin1
(
PinReq
*
req
);
error
_headWait
(
zodb
::
Tid
at
);
};
// FileH represent isolated file view under Conn.
...
...
wcfs/client/wcfs_misc.cpp
View file @
2c2a094f
...
...
@@ -34,6 +34,9 @@ using namespace golang;
#include <memory>
// golang::
namespace
golang
{
// os::
namespace
os
{
...
...
@@ -178,6 +181,46 @@ error unmap(void *addr, size_t size) {
}
// mm::
// io::ioutil::
namespace
io
{
namespace
ioutil
{
tuple
<
string
,
error
>
ReadFile
(
const
string
&
path
)
{
// errctx is ok as returned by all calls.
os
::
File
f
;
error
err
;
tie
(
f
,
err
)
=
os
::
open
(
path
);
if
(
err
!=
nil
)
return
make_tuple
(
""
,
err
);
// XXX defer close
string
data
;
vector
<
char
>
buf
(
4096
);
while
(
1
)
{
int
n
;
tie
(
n
,
err
)
=
f
->
read
(
&
buf
[
0
],
buf
.
size
());
data
.
append
(
&
buf
[
0
],
n
);
if
(
err
!=
nil
)
{
if
(
err
==
io
::
EOF_
)
err
=
nil
;
break
;
}
}
error
err2
=
f
->
close
();
if
(
err
==
nil
)
err
=
err2
;
if
(
err
!=
nil
)
data
=
""
;
return
make_tuple
(
data
,
err
);
}
}}
// io::ioutil::
// xstrconv:: (strconv-like)
namespace
xstrconv
{
...
...
@@ -215,6 +258,9 @@ tuple<uint64_t, error> parseUint(const string& s) {
}
// xstrconv::
}
// golang::
// xerr::
namespace
xerr
{
...
...
wcfs/client/wcfs_misc.h
View file @
2c2a094f
...
...
@@ -55,6 +55,9 @@ using std::vector;
#include <sys/stat.h>
#include <fcntl.h>
// golang::
namespace
golang
{
// os::
namespace
os
{
...
...
@@ -116,6 +119,13 @@ namespace mm {
}
// mm::
// io::ioutil::
namespace
io
{
namespace
ioutil
{
tuple
<
string
,
error
>
ReadFile
(
const
string
&
path
);
}}
// io::ioutil::
// ---- misc ----
...
...
@@ -129,6 +139,8 @@ tuple<uint64_t, error> parseUint(const string& s);
}
// xstrconv::
}
// golang::
// zodb::
namespace
zodb
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment