Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
L
libzmq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
libzmq
Commits
10d2b288
Unverified
Commit
10d2b288
authored
Mar 06, 2018
by
Luca Boccassi
Committed by
GitHub
Mar 06, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2971 from ZMQers/fix-static-init
Problem: static initialization order fiasco
parents
494c2a71
8cdfc8b9
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
50 additions
and
15 deletions
+50
-15
random.cpp
src/random.cpp
+50
-15
No files found.
src/random.cpp
View file @
10d2b288
...
@@ -79,19 +79,52 @@ uint32_t zmq::generate_random ()
...
@@ -79,19 +79,52 @@ uint32_t zmq::generate_random ()
// The context class cannot be used with static variables as the curve
// The context class cannot be used with static variables as the curve
// utility APIs like zmq_curve_keypair also call into the crypto
// utility APIs like zmq_curve_keypair also call into the crypto
// library.
// library.
// The safest solution for all use cases therefore is to have a
global,
// The safest solution for all use cases therefore is to have a
// static lock to serialize calls into an initialiser and a finaliser,
// static lock to serialize calls into an initialiser and a finaliser,
// using refcounts to make sure that a thread does not close the library
// using refcounts to make sure that a thread does not close the library
// while another is still using it.
// while another is still using it. To avoid the static initialization
// order fiasco, this is done using function-local statics, if the
// compiler implementation supports thread-safe initialization of those.
// Otherwise, we fall back to global statics.
// TODO if there is some other user of libsodium besides libzmq, this must
// be synchronized by the application. This should probably also be
// configurable via config.h
// TODO this should probably be done via config.h
#if __cplusplus >= 201103L \
|| (defined(__cpp_threadsafe_static_init) \
&& __cpp_threadsafe_static_init >= 200806) \
|| (defined(_MSC_VER) && _MSC_VER >= 1900)
#define ZMQ_HAVE_THREADSAFE_STATIC_LOCAL_INIT 1
// TODO this might probably also be set if a sufficiently recent gcc is used
// without -fno-threadsafe-statics, but this cannot be determined at
// compile-time, so it must be set via config.h
#else
#define ZMQ_HAVE_THREADSAFE_STATIC_LOCAL_INIT 0
#endif
#if !ZMQ_HAVE_THREADSAFE_STATIC_LOCAL_INIT \
&& (defined(ZMQ_USE_LIBSODIUM) \
|| (defined(ZMQ_USE_TWEETNACL) && !defined(ZMQ_HAVE_WINDOWS) \
&& !defined(ZMQ_HAVE_GETRANDOM)))
static
unsigned
int
random_refcount
=
0
;
static
unsigned
int
random_refcount
=
0
;
static
zmq
::
mutex_t
random_sync
;
static
zmq
::
mutex_t
random_sync
;
#endif
void
zmq
::
random_open
(
void
)
static
void
manage_random
(
bool
init
)
{
{
#if defined(ZMQ_USE_LIBSODIUM) \
#if defined(ZMQ_USE_LIBSODIUM) \
|| (defined(ZMQ_USE_TWEETNACL) && !defined(ZMQ_HAVE_WINDOWS) \
|| (defined(ZMQ_USE_TWEETNACL) && !defined(ZMQ_HAVE_WINDOWS) \
&& !defined(ZMQ_HAVE_GETRANDOM))
&& !defined(ZMQ_HAVE_GETRANDOM))
scoped_lock_t
locker
(
random_sync
);
#if ZMQ_HAVE_THREADSAFE_STATIC_LOCAL_INIT
static
int
random_refcount
=
0
;
static
zmq
::
mutex_t
random_sync
;
#endif
if
(
init
)
{
zmq
::
scoped_lock_t
locker
(
random_sync
);
if
(
random_refcount
==
0
)
{
if
(
random_refcount
==
0
)
{
int
rc
=
sodium_init
();
int
rc
=
sodium_init
();
...
@@ -99,21 +132,23 @@ void zmq::random_open (void)
...
@@ -99,21 +132,23 @@ void zmq::random_open (void)
}
}
++
random_refcount
;
++
random_refcount
;
#else
}
else
{
LIBZMQ_UNUSED
(
random_refcount
);
zmq
::
scoped_lock_t
locker
(
random_sync
);
#endif
}
void
zmq
::
random_close
(
void
)
{
#if defined(ZMQ_USE_LIBSODIUM) \
|| (defined(ZMQ_USE_TWEETNACL) && !defined(ZMQ_HAVE_WINDOWS) \
&& !defined(ZMQ_HAVE_GETRANDOM))
scoped_lock_t
locker
(
random_sync
);
--
random_refcount
;
--
random_refcount
;
if
(
random_refcount
==
0
)
{
if
(
random_refcount
==
0
)
{
randombytes_close
();
randombytes_close
();
}
}
}
#endif
#endif
}
}
void
zmq
::
random_open
(
void
)
{
manage_random
(
true
);
}
void
zmq
::
random_close
(
void
)
{
manage_random
(
false
);
}
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