Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
C
condenser
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Container registry
Model registry
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
hive
condenser
Commits
859c9912
Commit
859c9912
authored
8 years ago
by
theoreticalbts
Browse files
Options
Downloads
Patches
Plain Diff
Force calling code to correctly lock database
parent
f1d4734e
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
include/chainbase/chainbase.hpp
+61
-3
61 additions, 3 deletions
include/chainbase/chainbase.hpp
src/chainbase.cpp
+7
-0
7 additions, 0 deletions
src/chainbase.cpp
with
68 additions
and
3 deletions
include/chainbase/chainbase.hpp
+
61
−
3
View file @
859c9912
...
...
@@ -133,6 +133,29 @@ namespace chainbase {
int64_t
revision
=
0
;
};
/**
* The code we want to implement is this:
*
* ++target; try { ... } finally { --target }
*
* In C++ the only way to implement finally is to create a class
* with a destructor, so that's what we do here.
*/
class
int_incrementer
{
public:
int_incrementer
(
int32_t
&
target
)
:
_target
(
target
)
{
++
_target
;
}
~
int_incrementer
()
{
--
_target
;
}
int32_t
get
()
const
{
return
_target
;
}
private
:
int32_t
&
_target
;
};
/**
* The value_type stored in the multiindex container must have a integer field with the name 'id'. This will
* be the primary key and it will be assigned and managed by generic_index.
...
...
@@ -616,6 +639,20 @@ namespace chainbase {
void
flush
();
void
wipe
(
const
bfs
::
path
&
dir
);
void
require_lock_fail
(
const
char
*
lock_type
)
const
;
void
require_read_lock
()
const
{
if
(
_read_lock_count
<=
0
)
require_lock_fail
(
"read"
);
}
void
require_write_lock
()
{
if
(
_write_lock_count
<=
0
)
require_lock_fail
(
"write"
);
}
struct
session
{
public:
session
(
session
&&
s
)
:
_index_sessions
(
std
::
move
(
s
.
_index_sessions
)
),
_revision
(
s
.
_revision
){}
...
...
@@ -672,6 +709,7 @@ namespace chainbase {
void
set_revision
(
uint64_t
revision
)
{
require_write_lock
();
for
(
auto
i
:
_index_list
)
i
->
set_revision
(
revision
);
}
...
...
@@ -716,7 +754,9 @@ namespace chainbase {
}
template
<
typename
MultiIndexType
>
const
generic_index
<
MultiIndexType
>&
get_index
()
const
{
const
generic_index
<
MultiIndexType
>&
get_index
()
const
{
require_read_lock
();
typedef
generic_index
<
MultiIndexType
>
index_type
;
typedef
index_type
*
index_type_ptr
;
assert
(
_index_map
.
size
()
>
index_type
::
value_type
::
type_id
);
...
...
@@ -725,7 +765,9 @@ namespace chainbase {
}
template
<
typename
MultiIndexType
,
typename
ByIndex
>
auto
get_index
()
const
->
decltype
(
((
generic_index
<
MultiIndexType
>*
)(
nullptr
))
->
indicies
().
template
get
<
ByIndex
>()
)
{
auto
get_index
()
const
->
decltype
(
((
generic_index
<
MultiIndexType
>*
)(
nullptr
))
->
indicies
().
template
get
<
ByIndex
>()
)
{
require_read_lock
();
typedef
generic_index
<
MultiIndexType
>
index_type
;
typedef
index_type
*
index_type_ptr
;
assert
(
_index_map
.
size
()
>
index_type
::
value_type
::
type_id
);
...
...
@@ -734,7 +776,9 @@ namespace chainbase {
}
template
<
typename
MultiIndexType
>
generic_index
<
MultiIndexType
>&
get_mutable_index
()
{
generic_index
<
MultiIndexType
>&
get_mutable_index
()
{
require_write_lock
();
typedef
generic_index
<
MultiIndexType
>
index_type
;
typedef
index_type
*
index_type_ptr
;
assert
(
_index_map
.
size
()
>
index_type
::
value_type
::
type_id
);
...
...
@@ -745,6 +789,7 @@ namespace chainbase {
template
<
typename
ObjectType
,
typename
IndexedByType
,
typename
CompatibleKey
>
const
ObjectType
*
find
(
CompatibleKey
&&
key
)
const
{
require_read_lock
();
typedef
typename
get_index_type
<
ObjectType
>::
type
index_type
;
const
auto
&
idx
=
get_index
<
index_type
>
().
indicies
().
template
get
<
IndexedByType
>();
auto
itr
=
idx
.
find
(
std
::
forward
<
CompatibleKey
>
(
key
)
);
...
...
@@ -755,6 +800,7 @@ namespace chainbase {
template
<
typename
ObjectType
>
const
ObjectType
*
find
(
oid
<
ObjectType
>
key
=
oid
<
ObjectType
>
()
)
const
{
require_read_lock
();
typedef
typename
get_index_type
<
ObjectType
>::
type
index_type
;
const
auto
&
idx
=
get_index
<
index_type
>
().
indices
();
auto
itr
=
idx
.
find
(
key
);
...
...
@@ -765,6 +811,7 @@ namespace chainbase {
template
<
typename
ObjectType
,
typename
IndexedByType
,
typename
CompatibleKey
>
const
ObjectType
&
get
(
CompatibleKey
&&
key
)
const
{
require_read_lock
();
auto
obj
=
find
<
ObjectType
,
IndexedByType
>
(
std
::
forward
<
CompatibleKey
>
(
key
)
);
if
(
!
obj
)
BOOST_THROW_EXCEPTION
(
std
::
out_of_range
(
"unknown key"
)
);
return
*
obj
;
...
...
@@ -773,6 +820,7 @@ namespace chainbase {
template
<
typename
ObjectType
>
const
ObjectType
&
get
(
const
oid
<
ObjectType
>&
key
=
oid
<
ObjectType
>
()
)
const
{
require_read_lock
();
auto
obj
=
find
<
ObjectType
>
(
key
);
if
(
!
obj
)
BOOST_THROW_EXCEPTION
(
std
::
out_of_range
(
"unknown key"
)
);
return
*
obj
;
...
...
@@ -781,6 +829,7 @@ namespace chainbase {
template
<
typename
ObjectType
,
typename
Modifier
>
void
modify
(
const
ObjectType
&
obj
,
Modifier
&&
m
)
{
require_write_lock
();
typedef
typename
get_index_type
<
ObjectType
>::
type
index_type
;
get_mutable_index
<
index_type
>
().
modify
(
obj
,
m
);
}
...
...
@@ -788,6 +837,7 @@ namespace chainbase {
template
<
typename
ObjectType
>
void
remove
(
const
ObjectType
&
obj
)
{
require_write_lock
();
typedef
typename
get_index_type
<
ObjectType
>::
type
index_type
;
return
get_mutable_index
<
index_type
>
().
remove
(
obj
);
}
...
...
@@ -795,6 +845,7 @@ namespace chainbase {
template
<
typename
ObjectType
,
typename
Constructor
>
const
ObjectType
&
create
(
Constructor
&&
con
)
{
require_write_lock
();
typedef
typename
get_index_type
<
ObjectType
>::
type
index_type
;
return
get_mutable_index
<
index_type
>
().
emplace
(
std
::
forward
<
Constructor
>
(
con
)
);
}
...
...
@@ -803,6 +854,8 @@ namespace chainbase {
auto
with_read_lock
(
Lambda
&&
callback
,
uint64_t
wait_micro
=
1000000
)
->
decltype
(
(
*
(
Lambda
*
)
nullptr
)()
)
{
read_lock
lock
(
_rw_manager
->
current_lock
(),
bip
::
defer_lock_type
()
);
int_incrementer
ii
(
_read_lock_count
);
ii
.
get
();
// prevent unused variable warning
if
(
!
wait_micro
)
{
...
...
@@ -825,6 +878,8 @@ namespace chainbase {
BOOST_THROW_EXCEPTION
(
std
::
logic_error
(
"cannot acquire write lock on read-only process"
)
);
write_lock
lock
(
_rw_manager
->
current_lock
(),
boost
::
defer_lock_t
()
);
int_incrementer
ii
(
_write_lock_count
);
ii
.
get
();
// prevent unused variable warning
if
(
!
wait_micro
)
{
...
...
@@ -860,6 +915,9 @@ namespace chainbase {
vector
<
unique_ptr
<
abstract_index
>>
_index_map
;
bfs
::
path
_data_dir
;
int32_t
_read_lock_count
=
0
;
int32_t
_write_lock_count
=
0
;
};
template
<
typename
Object
,
typename
...
Args
>
...
...
This diff is collapsed.
Click to expand it.
src/chainbase.cpp
+
7
−
0
View file @
859c9912
...
...
@@ -130,6 +130,13 @@ namespace chainbase {
_index_map
.
clear
();
}
void
database
::
require_lock_fail
(
const
char
*
lock_type
)
const
{
std
::
string
err_msg
=
"require_"
+
std
::
string
(
lock_type
)
+
"_lock() failed"
;
std
::
cerr
<<
err_msg
<<
std
::
endl
;
BOOST_THROW_EXCEPTION
(
std
::
runtime_error
(
err_msg
)
);
}
void
database
::
undo
()
{
for
(
auto
&
item
:
_index_list
)
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment