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
6d698982
Unverified
Commit
6d698982
authored
Jan 26, 2020
by
Luca Boccassi
Committed by
GitHub
Jan 26, 2020
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #3794 from sigiesec/fix-ctx-shutdown
Problem: sockets can be created after calling zmq_ctx_shutdown
parents
fbf85448
36a8df2f
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
63 additions
and
17 deletions
+63
-17
zmq_ctx_shutdown.txt
doc/zmq_ctx_shutdown.txt
+3
-1
zmq_socket.txt
doc/zmq_socket.txt
+1
-1
ctx.cpp
src/ctx.cpp
+17
-14
test_ctx_destroy.cpp
tests/test_ctx_destroy.cpp
+42
-1
No files found.
doc/zmq_ctx_shutdown.txt
View file @
6d698982
...
...
@@ -19,7 +19,9 @@ The _zmq_ctx_shutdown()_ function shall shutdown the 0MQ context 'context'.
Context shutdown will cause any blocking operations currently in progress on
sockets open within 'context' to return immediately with an error code of ETERM.
With the exception of _zmq_close()_, any further operations on sockets open within
'context' shall fail with an error code of ETERM.
'context' shall fail with an error code of ETERM. No further sockets can be created
using _zmq_socket()_ on a context for which _zmq_ctx_shutdown()_ has been called,
it will return and set errno to ETERM.
This function is optional, client code is still required to call the linkzmq:zmq_ctx_term[3]
function to free all resources allocated by zeromq.
...
...
doc/zmq_socket.txt
View file @
6d698982
...
...
@@ -556,7 +556,7 @@ The provided 'context' is invalid.
*EMFILE*::
The limit on the total number of open 0MQ sockets has been reached.
*ETERM*::
The context specified was terminated.
The context specified was
shutdown or
terminated.
EXAMPLE
-------
...
...
src/ctx.cpp
View file @
6d698982
...
...
@@ -232,16 +232,18 @@ int zmq::ctx_t::shutdown ()
{
scoped_lock_t
locker
(
_slot_sync
);
if
(
!
_
starting
&&
!
_
terminating
)
{
if
(
!
_terminating
)
{
_terminating
=
true
;
// Send stop command to sockets so that any blocking calls
// can be interrupted. If there are no sockets we can ask reaper
// thread to stop.
for
(
sockets_t
::
size_type
i
=
0
;
i
!=
_sockets
.
size
();
i
++
)
_sockets
[
i
]
->
stop
();
if
(
_sockets
.
empty
())
_reaper
->
stop
();
if
(
!
_starting
)
{
// Send stop command to sockets so that any blocking calls
// can be interrupted. If there are no sockets we can ask reaper
// thread to stop.
for
(
sockets_t
::
size_type
i
=
0
;
i
!=
_sockets
.
size
();
i
++
)
_sockets
[
i
]
->
stop
();
if
(
_sockets
.
empty
())
_reaper
->
stop
();
}
}
return
0
;
...
...
@@ -471,17 +473,18 @@ zmq::socket_base_t *zmq::ctx_t::create_socket (int type_)
{
scoped_lock_t
locker
(
_slot_sync
);
if
(
unlikely
(
_starting
))
{
if
(
!
start
())
return
NULL
;
}
// Once zmq_ctx_term() was called, we can't create new sockets.
// Once zmq_ctx_term() or zmq_ctx_shutdown() was called, we can't create
// new sockets.
if
(
_terminating
)
{
errno
=
ETERM
;
return
NULL
;
}
if
(
unlikely
(
_starting
))
{
if
(
!
start
())
return
NULL
;
}
// If max_sockets limit was reached, return error.
if
(
_empty_slots
.
empty
())
{
errno
=
EMFILE
;
...
...
tests/test_ctx_destroy.cpp
View file @
6d698982
...
...
@@ -88,7 +88,46 @@ void test_ctx_shutdown ()
// Close the socket.
TEST_ASSERT_SUCCESS_ERRNO
(
zmq_close
(
socket
));
// Destory the context, will now not hang as we have closed the socket.
// Destroy the context, will now not hang as we have closed the socket.
TEST_ASSERT_SUCCESS_ERRNO
(
zmq_ctx_destroy
(
ctx
));
}
void
test_ctx_shutdown_socket_opened_after
()
{
// Set up our context.
void
*
ctx
=
zmq_ctx_new
();
TEST_ASSERT_NOT_NULL
(
ctx
);
// Open a socket to start context, and close it immediately again.
void
*
socket
=
zmq_socket
(
ctx
,
ZMQ_PULL
);
TEST_ASSERT_NOT_NULL
(
socket
);
TEST_ASSERT_SUCCESS_ERRNO
(
zmq_close
(
socket
));
// Shutdown context.
TEST_ASSERT_SUCCESS_ERRNO
(
zmq_ctx_shutdown
(
ctx
));
// Opening socket should now fail.
TEST_ASSERT_NULL
(
zmq_socket
(
ctx
,
ZMQ_PULL
));
TEST_ASSERT_FAILURE_ERRNO
(
ETERM
,
-
1
);
// Destroy the context.
TEST_ASSERT_SUCCESS_ERRNO
(
zmq_ctx_destroy
(
ctx
));
}
void
test_ctx_shutdown_only_socket_opened_after
()
{
// Set up our context.
void
*
ctx
=
zmq_ctx_new
();
TEST_ASSERT_NOT_NULL
(
ctx
);
// Shutdown context.
TEST_ASSERT_SUCCESS_ERRNO
(
zmq_ctx_shutdown
(
ctx
));
// Opening socket should now fail.
TEST_ASSERT_NULL
(
zmq_socket
(
ctx
,
ZMQ_PULL
));
TEST_ASSERT_FAILURE_ERRNO
(
ETERM
,
-
1
);
// Destroy the context.
TEST_ASSERT_SUCCESS_ERRNO
(
zmq_ctx_destroy
(
ctx
));
}
...
...
@@ -201,6 +240,8 @@ int main (void)
UNITY_BEGIN
();
RUN_TEST
(
test_ctx_destroy
);
RUN_TEST
(
test_ctx_shutdown
);
RUN_TEST
(
test_ctx_shutdown_socket_opened_after
);
RUN_TEST
(
test_ctx_shutdown_only_socket_opened_after
);
RUN_TEST
(
test_zmq_ctx_term_null_fails
);
RUN_TEST
(
test_zmq_term_null_fails
);
RUN_TEST
(
test_zmq_ctx_shutdown_null_fails
);
...
...
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