Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
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
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
e9a5f288
Commit
e9a5f288
authored
Jan 09, 2019
by
Sergey Vojtovich
Committed by
Eugene Kosov
Jun 26, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MDEV-17441 - InnoDB transition to C++11 atomics
Get rid of os_once.
parent
04ee9619
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
24 additions
and
123 deletions
+24
-123
storage/innobase/dict/dict0dict.cc
storage/innobase/dict/dict0dict.cc
+4
-38
storage/innobase/dict/dict0mem.cc
storage/innobase/dict/dict0mem.cc
+0
-4
storage/innobase/handler/ha_innodb.cc
storage/innobase/handler/ha_innodb.cc
+16
-18
storage/innobase/include/dict0dict.h
storage/innobase/include/dict0dict.h
+3
-17
storage/innobase/include/dict0mem.h
storage/innobase/include/dict0mem.h
+1
-46
No files found.
storage/innobase/dict/dict0dict.cc
View file @
e9a5f288
...
@@ -707,20 +707,6 @@ dict_table_get_nth_v_col_mysql(
...
@@ -707,20 +707,6 @@ dict_table_get_nth_v_col_mysql(
return
(
dict_table_get_nth_v_col
(
table
,
i
));
return
(
dict_table_get_nth_v_col
(
table
,
i
));
}
}
/** Allocate and init the autoinc latch of a given table.
This function must not be called concurrently on the same table object.
@param[in,out] table_void table whose autoinc latch to create */
static
void
dict_table_autoinc_alloc
(
void
*
table_void
)
{
dict_table_t
*
table
=
static_cast
<
dict_table_t
*>
(
table_void
);
table
->
autoinc_mutex
=
UT_NEW_NOKEY
(
ib_mutex_t
());
ut_a
(
table
->
autoinc_mutex
!=
NULL
);
mutex_create
(
LATCH_ID_AUTOINC
,
table
->
autoinc_mutex
);
}
/** Allocate and init the zip_pad_mutex of a given index.
/** Allocate and init the zip_pad_mutex of a given index.
This function must not be called concurrently on the same index object.
This function must not be called concurrently on the same index object.
@param[in,out] index_void index whose zip_pad_mutex to create */
@param[in,out] index_void index whose zip_pad_mutex to create */
...
@@ -735,20 +721,6 @@ dict_index_zip_pad_alloc(
...
@@ -735,20 +721,6 @@ dict_index_zip_pad_alloc(
mutex_create
(
LATCH_ID_ZIP_PAD_MUTEX
,
index
->
zip_pad
.
mutex
);
mutex_create
(
LATCH_ID_ZIP_PAD_MUTEX
,
index
->
zip_pad
.
mutex
);
}
}
/********************************************************************//**
Acquire the autoinc lock. */
void
dict_table_autoinc_lock
(
/*====================*/
dict_table_t
*
table
)
/*!< in/out: table */
{
os_once
::
do_or_wait_for_done
(
&
table
->
autoinc_mutex_created
,
dict_table_autoinc_alloc
,
table
);
mutex_enter
(
table
->
autoinc_mutex
);
}
/** Acquire the zip_pad_mutex latch.
/** Acquire the zip_pad_mutex latch.
@param[in,out] index the index whose zip_pad_mutex to acquire.*/
@param[in,out] index the index whose zip_pad_mutex to acquire.*/
static
static
...
@@ -788,16 +760,6 @@ dict_table_get_all_fts_indexes(
...
@@ -788,16 +760,6 @@ dict_table_get_all_fts_indexes(
return
(
ib_vector_size
(
indexes
));
return
(
ib_vector_size
(
indexes
));
}
}
/********************************************************************//**
Release the autoinc lock. */
void
dict_table_autoinc_unlock
(
/*======================*/
dict_table_t
*
table
)
/*!< in/out: table */
{
mutex_exit
(
table
->
autoinc_mutex
);
}
/** Looks for column n in an index.
/** Looks for column n in an index.
@param[in] index index
@param[in] index index
@param[in] n column number
@param[in] n column number
...
@@ -1192,6 +1154,8 @@ inline void dict_sys_t::add(dict_table_t* table)
...
@@ -1192,6 +1154,8 @@ inline void dict_sys_t::add(dict_table_t* table)
ulint
fold
=
ut_fold_string
(
table
->
name
.
m_name
);
ulint
fold
=
ut_fold_string
(
table
->
name
.
m_name
);
mutex_create
(
LATCH_ID_AUTOINC
,
&
table
->
autoinc_mutex
);
/* Look for a table with the same name: error if such exists */
/* Look for a table with the same name: error if such exists */
{
{
dict_table_t
*
table2
;
dict_table_t
*
table2
;
...
@@ -1939,6 +1903,8 @@ void dict_sys_t::remove(dict_table_t* table, bool lru, bool keep)
...
@@ -1939,6 +1903,8 @@ void dict_sys_t::remove(dict_table_t* table, bool lru, bool keep)
UT_DELETE
(
table
->
vc_templ
);
UT_DELETE
(
table
->
vc_templ
);
}
}
mutex_free
(
&
table
->
autoinc_mutex
);
if
(
!
keep
)
{
if
(
!
keep
)
{
dict_mem_table_free
(
table
);
dict_mem_table_free
(
table
);
}
}
...
...
storage/innobase/dict/dict0mem.cc
View file @
e9a5f288
...
@@ -178,9 +178,6 @@ dict_mem_table_create(
...
@@ -178,9 +178,6 @@ dict_mem_table_create(
table
->
autoinc_lock
=
static_cast
<
ib_lock_t
*>
(
table
->
autoinc_lock
=
static_cast
<
ib_lock_t
*>
(
mem_heap_alloc
(
heap
,
lock_get_size
()));
mem_heap_alloc
(
heap
,
lock_get_size
()));
/* lazy creation of table autoinc latch */
dict_table_autoinc_create_lazy
(
table
);
/* If the table has an FTS index or we are in the process
/* If the table has an FTS index or we are in the process
of building one, create the table->fts */
of building one, create the table->fts */
if
(
dict_table_has_fts_index
(
table
)
if
(
dict_table_has_fts_index
(
table
)
...
@@ -217,7 +214,6 @@ dict_mem_table_free(
...
@@ -217,7 +214,6 @@ dict_mem_table_free(
}
}
}
}
dict_table_autoinc_destroy
(
table
);
dict_mem_table_free_foreign_vcol_set
(
table
);
dict_mem_table_free_foreign_vcol_set
(
table
);
dict_table_stats_latch_destroy
(
table
);
dict_table_stats_latch_destroy
(
table
);
...
...
storage/innobase/handler/ha_innodb.cc
View file @
e9a5f288
...
@@ -2626,8 +2626,7 @@ ha_innobase::innobase_reset_autoinc(
...
@@ -2626,8 +2626,7 @@ ha_innobase::innobase_reset_autoinc(
if
(
error
==
DB_SUCCESS
)
{
if
(
error
==
DB_SUCCESS
)
{
dict_table_autoinc_initialize
(
m_prebuilt
->
table
,
autoinc
);
dict_table_autoinc_initialize
(
m_prebuilt
->
table
,
autoinc
);
mutex_exit
(
&
m_prebuilt
->
table
->
autoinc_mutex
);
dict_table_autoinc_unlock
(
m_prebuilt
->
table
);
}
}
return
(
error
);
return
(
error
);
...
@@ -6056,7 +6055,7 @@ initialize_auto_increment(dict_table_t* table, const Field* field)
...
@@ -6056,7 +6055,7 @@ initialize_auto_increment(dict_table_t* table, const Field* field)
const
unsigned
col_no
=
innodb_col_no
(
field
);
const
unsigned
col_no
=
innodb_col_no
(
field
);
dict_table_autoinc_lock
(
table
);
mutex_enter
(
&
table
->
autoinc_mutex
);
table
->
persistent_autoinc
=
1
table
->
persistent_autoinc
=
1
+
dict_table_get_nth_col_pos
(
table
,
col_no
,
NULL
);
+
dict_table_get_nth_col_pos
(
table
,
col_no
,
NULL
);
...
@@ -6064,7 +6063,7 @@ initialize_auto_increment(dict_table_t* table, const Field* field)
...
@@ -6064,7 +6063,7 @@ initialize_auto_increment(dict_table_t* table, const Field* field)
if
(
table
->
autoinc
)
{
if
(
table
->
autoinc
)
{
/* Already initialized. Our caller checked
/* Already initialized. Our caller checked
table->persistent_autoinc without
table->persistent_autoinc without
dict_table_autoinc_lock()
, and there might be multiple
autoinc_mutex protection
, and there might be multiple
ha_innobase::open() executing concurrently. */
ha_innobase::open() executing concurrently. */
}
else
if
(
srv_force_recovery
>=
SRV_FORCE_NO_IBUF_MERGE
)
{
}
else
if
(
srv_force_recovery
>=
SRV_FORCE_NO_IBUF_MERGE
)
{
/* If the recovery level is set so high that writes
/* If the recovery level is set so high that writes
...
@@ -6086,7 +6085,7 @@ initialize_auto_increment(dict_table_t* table, const Field* field)
...
@@ -6086,7 +6085,7 @@ initialize_auto_increment(dict_table_t* table, const Field* field)
innobase_get_int_col_max_value
(
field
));
innobase_get_int_col_max_value
(
field
));
}
}
dict_table_autoinc_unlock
(
table
);
mutex_exit
(
&
table
->
autoinc_mutex
);
}
}
/** Open an InnoDB table
/** Open an InnoDB table
...
@@ -7922,7 +7921,7 @@ ha_innobase::innobase_lock_autoinc(void)
...
@@ -7922,7 +7921,7 @@ ha_innobase::innobase_lock_autoinc(void)
switch
(
innobase_autoinc_lock_mode
)
{
switch
(
innobase_autoinc_lock_mode
)
{
case
AUTOINC_NO_LOCKING
:
case
AUTOINC_NO_LOCKING
:
/* Acquire only the AUTOINC mutex. */
/* Acquire only the AUTOINC mutex. */
dict_table_autoinc_lock
(
m_prebuilt
->
table
);
mutex_enter
(
&
m_prebuilt
->
table
->
autoinc_mutex
);
break
;
break
;
case
AUTOINC_NEW_STYLE_LOCKING
:
case
AUTOINC_NEW_STYLE_LOCKING
:
...
@@ -7937,14 +7936,14 @@ ha_innobase::innobase_lock_autoinc(void)
...
@@ -7937,14 +7936,14 @@ ha_innobase::innobase_lock_autoinc(void)
)
{
)
{
/* Acquire the AUTOINC mutex. */
/* Acquire the AUTOINC mutex. */
dict_table_autoinc_lock
(
m_prebuilt
->
table
);
mutex_enter
(
&
m_prebuilt
->
table
->
autoinc_mutex
);
/* We need to check that another transaction isn't
/* We need to check that another transaction isn't
already holding the AUTOINC lock on the table. */
already holding the AUTOINC lock on the table. */
if
(
m_prebuilt
->
table
->
n_waiting_or_granted_auto_inc_locks
)
{
if
(
m_prebuilt
->
table
->
n_waiting_or_granted_auto_inc_locks
)
{
/* Release the mutex to avoid deadlocks and
/* Release the mutex to avoid deadlocks and
fall back to old style locking. */
fall back to old style locking. */
dict_table_autoinc_unlock
(
m_prebuilt
->
table
);
mutex_exit
(
&
m_prebuilt
->
table
->
autoinc_mutex
);
}
else
{
}
else
{
/* Do not fall back to old style locking. */
/* Do not fall back to old style locking. */
break
;
break
;
...
@@ -7960,7 +7959,7 @@ ha_innobase::innobase_lock_autoinc(void)
...
@@ -7960,7 +7959,7 @@ ha_innobase::innobase_lock_autoinc(void)
if
(
error
==
DB_SUCCESS
)
{
if
(
error
==
DB_SUCCESS
)
{
/* Acquire the AUTOINC mutex. */
/* Acquire the AUTOINC mutex. */
dict_table_autoinc_lock
(
m_prebuilt
->
table
);
mutex_enter
(
&
m_prebuilt
->
table
->
autoinc_mutex
);
}
}
break
;
break
;
...
@@ -7988,8 +7987,7 @@ ha_innobase::innobase_set_max_autoinc(
...
@@ -7988,8 +7987,7 @@ ha_innobase::innobase_set_max_autoinc(
if
(
error
==
DB_SUCCESS
)
{
if
(
error
==
DB_SUCCESS
)
{
dict_table_autoinc_update_if_greater
(
m_prebuilt
->
table
,
auto_inc
);
dict_table_autoinc_update_if_greater
(
m_prebuilt
->
table
,
auto_inc
);
mutex_exit
(
&
m_prebuilt
->
table
->
autoinc_mutex
);
dict_table_autoinc_unlock
(
m_prebuilt
->
table
);
}
}
return
(
error
);
return
(
error
);
...
@@ -12588,7 +12586,7 @@ create_table_info_t::create_table_update_dict()
...
@@ -12588,7 +12586,7 @@ create_table_info_t::create_table_update_dict()
autoinc
=
1
;
autoinc
=
1
;
}
}
dict_table_autoinc_lock
(
innobase_table
);
mutex_enter
(
&
innobase_table
->
autoinc_mutex
);
dict_table_autoinc_initialize
(
innobase_table
,
autoinc
);
dict_table_autoinc_initialize
(
innobase_table
,
autoinc
);
if
(
innobase_table
->
is_temporary
())
{
if
(
innobase_table
->
is_temporary
())
{
...
@@ -12613,7 +12611,7 @@ create_table_info_t::create_table_update_dict()
...
@@ -12613,7 +12611,7 @@ create_table_info_t::create_table_update_dict()
}
}
}
}
dict_table_autoinc_unlock
(
innobase_table
);
mutex_exit
(
&
innobase_table
->
autoinc_mutex
);
}
}
innobase_parse_hint_from_comment
(
m_thd
,
innobase_table
,
m_form
->
s
);
innobase_parse_hint_from_comment
(
m_thd
,
innobase_table
,
m_form
->
s
);
...
@@ -16460,7 +16458,7 @@ ha_innobase::innobase_get_autoinc(
...
@@ -16460,7 +16458,7 @@ ha_innobase::innobase_get_autoinc(
/* It should have been initialized during open. */
/* It should have been initialized during open. */
if
(
*
value
==
0
)
{
if
(
*
value
==
0
)
{
m_prebuilt
->
autoinc_error
=
DB_UNSUPPORTED
;
m_prebuilt
->
autoinc_error
=
DB_UNSUPPORTED
;
dict_table_autoinc_unlock
(
m_prebuilt
->
table
);
mutex_exit
(
&
m_prebuilt
->
table
->
autoinc_mutex
);
}
}
}
}
...
@@ -16484,7 +16482,7 @@ ha_innobase::innobase_peek_autoinc(void)
...
@@ -16484,7 +16482,7 @@ ha_innobase::innobase_peek_autoinc(void)
innodb_table
=
m_prebuilt
->
table
;
innodb_table
=
m_prebuilt
->
table
;
dict_table_autoinc_lock
(
innodb_table
);
mutex_enter
(
&
innodb_table
->
autoinc_mutex
);
auto_inc
=
dict_table_autoinc_read
(
innodb_table
);
auto_inc
=
dict_table_autoinc_read
(
innodb_table
);
...
@@ -16493,7 +16491,7 @@ ha_innobase::innobase_peek_autoinc(void)
...
@@ -16493,7 +16491,7 @@ ha_innobase::innobase_peek_autoinc(void)
" '"
<<
innodb_table
->
name
<<
"'"
;
" '"
<<
innodb_table
->
name
<<
"'"
;
}
}
dict_table_autoinc_unlock
(
innodb_table
);
mutex_exit
(
&
innodb_table
->
autoinc_mutex
);
return
(
auto_inc
);
return
(
auto_inc
);
}
}
...
@@ -16600,7 +16598,7 @@ ha_innobase::get_auto_increment(
...
@@ -16600,7 +16598,7 @@ ha_innobase::get_auto_increment(
/* Out of range number. Let handler::update_auto_increment()
/* Out of range number. Let handler::update_auto_increment()
take care of this */
take care of this */
m_prebuilt
->
autoinc_last_value
=
0
;
m_prebuilt
->
autoinc_last_value
=
0
;
dict_table_autoinc_unlock
(
m_prebuilt
->
table
);
mutex_exit
(
&
m_prebuilt
->
table
->
autoinc_mutex
);
*
nb_reserved_values
=
0
;
*
nb_reserved_values
=
0
;
return
;
return
;
}
}
...
@@ -16664,7 +16662,7 @@ ha_innobase::get_auto_increment(
...
@@ -16664,7 +16662,7 @@ ha_innobase::get_auto_increment(
m_prebuilt
->
autoinc_offset
=
offset
;
m_prebuilt
->
autoinc_offset
=
offset
;
m_prebuilt
->
autoinc_increment
=
increment
;
m_prebuilt
->
autoinc_increment
=
increment
;
dict_table_autoinc_unlock
(
m_prebuilt
->
table
);
mutex_exit
(
&
m_prebuilt
->
table
->
autoinc_mutex
);
}
}
/*******************************************************************//**
/*******************************************************************//**
...
...
storage/innobase/include/dict0dict.h
View file @
e9a5f288
...
@@ -288,13 +288,6 @@ dict_col_name_is_reserved(
...
@@ -288,13 +288,6 @@ dict_col_name_is_reserved(
/*======================*/
/*======================*/
const
char
*
name
)
/*!< in: column name */
const
char
*
name
)
/*!< in: column name */
MY_ATTRIBUTE
((
nonnull
,
warn_unused_result
));
MY_ATTRIBUTE
((
nonnull
,
warn_unused_result
));
/********************************************************************//**
Acquire the autoinc lock. */
void
dict_table_autoinc_lock
(
/*====================*/
dict_table_t
*
table
)
/*!< in/out: table */
MY_ATTRIBUTE
((
nonnull
));
/** Unconditionally set the AUTO_INCREMENT counter.
/** Unconditionally set the AUTO_INCREMENT counter.
@param[in,out] table table or partition
@param[in,out] table table or partition
@param[in] value next available AUTO_INCREMENT value */
@param[in] value next available AUTO_INCREMENT value */
...
@@ -303,7 +296,7 @@ UNIV_INLINE
...
@@ -303,7 +296,7 @@ UNIV_INLINE
void
void
dict_table_autoinc_initialize
(
dict_table_t
*
table
,
ib_uint64_t
value
)
dict_table_autoinc_initialize
(
dict_table_t
*
table
,
ib_uint64_t
value
)
{
{
ut_ad
(
dict_table_autoinc_own
(
table
));
ut_ad
(
mutex_own
(
&
table
->
autoinc_mutex
));
table
->
autoinc
=
value
;
table
->
autoinc
=
value
;
}
}
...
@@ -316,7 +309,7 @@ UNIV_INLINE
...
@@ -316,7 +309,7 @@ UNIV_INLINE
ib_uint64_t
ib_uint64_t
dict_table_autoinc_read
(
const
dict_table_t
*
table
)
dict_table_autoinc_read
(
const
dict_table_t
*
table
)
{
{
ut_ad
(
dict_table_autoinc_own
(
table
));
ut_ad
(
mutex_own
(
&
table
->
autoinc_mutex
));
return
(
table
->
autoinc
);
return
(
table
->
autoinc
);
}
}
...
@@ -330,7 +323,7 @@ UNIV_INLINE
...
@@ -330,7 +323,7 @@ UNIV_INLINE
bool
bool
dict_table_autoinc_update_if_greater
(
dict_table_t
*
table
,
ib_uint64_t
value
)
dict_table_autoinc_update_if_greater
(
dict_table_t
*
table
,
ib_uint64_t
value
)
{
{
ut_ad
(
dict_table_autoinc_own
(
table
));
ut_ad
(
mutex_own
(
&
table
->
autoinc_mutex
));
if
(
value
>
table
->
autoinc
)
{
if
(
value
>
table
->
autoinc
)
{
...
@@ -341,13 +334,6 @@ dict_table_autoinc_update_if_greater(dict_table_t* table, ib_uint64_t value)
...
@@ -341,13 +334,6 @@ dict_table_autoinc_update_if_greater(dict_table_t* table, ib_uint64_t value)
return
(
false
);
return
(
false
);
}
}
/********************************************************************//**
Release the autoinc lock. */
void
dict_table_autoinc_unlock
(
/*======================*/
dict_table_t
*
table
)
/*!< in/out: table */
MY_ATTRIBUTE
((
nonnull
));
/**********************************************************************//**
/**********************************************************************//**
Adds system columns to a table object. */
Adds system columns to a table object. */
void
void
...
...
storage/innobase/include/dict0mem.h
View file @
e9a5f288
...
@@ -2103,11 +2103,8 @@ struct dict_table_t {
...
@@ -2103,11 +2103,8 @@ struct dict_table_t {
from a select. */
from a select. */
lock_t
*
autoinc_lock
;
lock_t
*
autoinc_lock
;
/** Creation state of autoinc_mutex member */
volatile
os_once
::
state_t
autoinc_mutex_created
;
/** Mutex protecting the autoincrement counter. */
/** Mutex protecting the autoincrement counter. */
ib_mutex_t
*
autoinc_mutex
;
ib_mutex_t
autoinc_mutex
;
/** Autoinc counter value to give to the next inserted row. */
/** Autoinc counter value to give to the next inserted row. */
ib_uint64_t
autoinc
;
ib_uint64_t
autoinc
;
...
@@ -2292,35 +2289,6 @@ struct dict_foreign_add_to_referenced_table {
...
@@ -2292,35 +2289,6 @@ struct dict_foreign_add_to_referenced_table {
}
}
};
};
/** Destroy the autoinc latch of the given table.
This function is only called from either single threaded environment
or from a thread that has not shared the table object with other threads.
@param[in,out] table table whose stats latch to destroy */
inline
void
dict_table_autoinc_destroy
(
dict_table_t
*
table
)
{
if
(
table
->
autoinc_mutex_created
==
os_once
::
DONE
&&
table
->
autoinc_mutex
!=
NULL
)
{
mutex_free
(
table
->
autoinc_mutex
);
UT_DELETE
(
table
->
autoinc_mutex
);
}
}
/** Request for lazy creation of the autoinc latch of a given table.
This function is only called from either single threaded environment
or from a thread that has not shared the table object with other threads.
@param[in,out] table table whose autoinc latch is to be created. */
inline
void
dict_table_autoinc_create_lazy
(
dict_table_t
*
table
)
{
table
->
autoinc_mutex
=
NULL
;
table
->
autoinc_mutex_created
=
os_once
::
NEVER_DONE
;
}
/** Request a lazy creation of dict_index_t::zip_pad::mutex.
/** Request a lazy creation of dict_index_t::zip_pad::mutex.
This function is only called from either single threaded environment
This function is only called from either single threaded environment
or from a thread that has not shared the table object with other threads.
or from a thread that has not shared the table object with other threads.
...
@@ -2360,19 +2328,6 @@ dict_index_zip_pad_unlock(
...
@@ -2360,19 +2328,6 @@ dict_index_zip_pad_unlock(
mutex_exit
(
index
->
zip_pad
.
mutex
);
mutex_exit
(
index
->
zip_pad
.
mutex
);
}
}
#ifdef UNIV_DEBUG
/** Check if the current thread owns the autoinc_mutex of a given table.
@param[in] table the autoinc_mutex belongs to this table
@return true, if the current thread owns the autoinc_mutex, false otherwise.*/
inline
bool
dict_table_autoinc_own
(
const
dict_table_t
*
table
)
{
return
(
mutex_own
(
table
->
autoinc_mutex
));
}
#endif
/* UNIV_DEBUG */
/** Check whether the col is used in spatial index or regular index.
/** Check whether the col is used in spatial index or regular index.
@param[in] col column to check
@param[in] col column to check
@return spatial status */
@return spatial status */
...
...
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