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
936dbf95
Commit
936dbf95
authored
Aug 12, 2010
by
Martin Sustrik
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dezombification procedure fixed
parent
76bd6e73
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
59 additions
and
23 deletions
+59
-23
ctx.cpp
src/ctx.cpp
+34
-12
ctx.hpp
src/ctx.hpp
+8
-4
object.cpp
src/object.cpp
+5
-0
object.hpp
src/object.hpp
+3
-0
socket_base.cpp
src/socket_base.cpp
+6
-4
socket_base.hpp
src/socket_base.hpp
+2
-2
zmq.cpp
src/zmq.cpp
+1
-1
No files found.
src/ctx.cpp
View file @
936dbf95
...
...
@@ -97,7 +97,7 @@ zmq::ctx_t::~ctx_t ()
#endif
}
int
zmq
::
ctx_t
::
term
()
int
zmq
::
ctx_t
::
term
inate
()
{
// First send stop command to sockets so that any
// blocking calls are interrupted.
...
...
@@ -115,12 +115,15 @@ int zmq::ctx_t::term ()
if
(
no_sockets_notify
)
no_sockets_sync
.
wait
();
// At this point there
's only one application thread (this one) remaining.
//
We don't even have to synchronise access to data
.
// At this point there
should be no active sockets. What we have is a set
//
of zombies waiting to be dezombified
.
zmq_assert
(
sockets
.
empty
());
// TODO: We are accessing the list of zombies in unsynchronised manner here!
// Get rid of remaining zombie sockets.
// Get rid of remaining zombie sockets. Note that the lock won't block
// anyone here. There's noone else having open sockets anyway. The only
// purpose of the lock is to double-check all the CPU caches have been
// synchronised.
slot_sync
.
lock
();
while
(
!
zombies
.
empty
())
{
dezombify
();
...
...
@@ -134,6 +137,7 @@ int zmq::ctx_t::term ()
usleep
(
1000
);
#endif
}
slot_sync
.
unlock
();
// Deallocate the resources.
delete
this
;
...
...
@@ -197,6 +201,22 @@ void zmq::ctx_t::zombify_socket (socket_base_t *socket_)
slot_sync
.
unlock
();
}
void
zmq
::
ctx_t
::
dezombify_socket
(
socket_base_t
*
socket_
)
{
// We assume that this function is called only within dezombification
// process, which in turn is running within a slot_sync critical section.
// Therefore, we need no locking here.
// TODO: Can we do this better than O(n)?
zombies_t
::
iterator
it
=
std
::
find
(
zombies
.
begin
(),
zombies
.
end
(),
socket_
);
zmq_assert
(
it
!=
zombies
.
end
());
// Move from the slot from 'zombie' to 'empty' state.
empty_slots
.
push_back
((
*
it
)
->
get_slot
());
zombies
.
erase
(
it
);
}
void
zmq
::
ctx_t
::
send_command
(
uint32_t
slot_
,
const
command_t
&
command_
)
{
slots
[
slot_
]
->
send
(
command_
);
...
...
@@ -287,12 +307,14 @@ void zmq::ctx_t::dezombify ()
{
// Try to dezombify each zombie in the list. Note that caller is
// responsible for calling this method in the slot_sync critical section.
for
(
zombies_t
::
size_type
i
=
0
;
i
!=
zombies
.
size
();)
if
(
zombies
[
i
]
->
dezombify
())
{
empty_slots
.
push_back
(
zombies
[
i
]
->
get_slot
());
zombies
.
erase
(
zombies
[
i
]);
}
else
i
++
;
zombies_t
::
iterator
it
=
zombies
.
begin
();
while
(
it
!=
zombies
.
end
())
{
zombies_t
::
iterator
old
=
it
;
++
it
;
// dezombify_socket can be called here that will invalidate
// the iterator. That's why we've got the next zombie beforehand.
(
*
old
)
->
dezombify
();
}
}
src/ctx.hpp
View file @
936dbf95
...
...
@@ -20,9 +20,10 @@
#ifndef __ZMQ_CTX_HPP_INCLUDED__
#define __ZMQ_CTX_HPP_INCLUDED__
#include <vector>
#include <set>
#include <map>
#include <list>
#include <vector>
#include <string>
#include "signaler.hpp"
...
...
@@ -52,7 +53,7 @@ namespace zmq
// no more sockets open it'll cause all the infrastructure to be shut
// down. If there are open sockets still, the deallocation happens
// after the last one is closed.
int
term
();
int
term
inate
();
// Create a socket.
class
socket_base_t
*
create_socket
(
int
type_
);
...
...
@@ -60,6 +61,9 @@ namespace zmq
// Make socket a zombie.
void
zombify_socket
(
socket_base_t
*
socket_
);
// Kill the zombie socket.
void
dezombify_socket
(
socket_base_t
*
socket_
);
// Send command to the destination slot.
void
send_command
(
uint32_t
slot_
,
const
command_t
&
command_
);
...
...
@@ -83,9 +87,9 @@ namespace zmq
typedef
yarray_t
<
socket_base_t
>
sockets_t
;
sockets_t
sockets
;
//
Array
of sockets that were already closed but not yet deallocated.
//
List
of sockets that were already closed but not yet deallocated.
// These sockets still have some pipes and I/O objects attached.
typedef
yarray_t
<
socket_base_t
>
zombies_t
;
typedef
std
::
list
<
socket_base_t
*
>
zombies_t
;
zombies_t
zombies
;
// List of unused slots.
...
...
src/object.cpp
View file @
936dbf95
...
...
@@ -147,6 +147,11 @@ void zmq::object_t::zombify_socket (socket_base_t *socket_)
ctx
->
zombify_socket
(
socket_
);
}
void
zmq
::
object_t
::
dezombify_socket
(
socket_base_t
*
socket_
)
{
ctx
->
dezombify_socket
(
socket_
);
}
void
zmq
::
object_t
::
send_stop
()
{
// 'stop' command goes always from administrative thread to
...
...
src/object.hpp
View file @
936dbf95
...
...
@@ -55,6 +55,9 @@ namespace zmq
// the context.
void
zombify_socket
(
class
socket_base_t
*
socket_
);
// Dezombify particular socket, i.e. destroy it.
void
dezombify_socket
(
class
socket_base_t
*
socket_
);
// Derived object can use these functions to send commands
// to other objects.
void
send_stop
();
...
...
src/socket_base.cpp
View file @
936dbf95
...
...
@@ -118,10 +118,15 @@ zmq::socket_base_t::socket_base_t (ctx_t *parent_, uint32_t slot_) :
zmq
::
socket_base_t
::~
socket_base_t
()
{
zmq_assert
(
zombie
);
// Check whether there are no session leaks.
sessions_sync
.
lock
();
zmq_assert
(
sessions
.
empty
());
sessions_sync
.
unlock
();
// Mark the socket slot as empty.
dezombify_socket
(
this
);
}
zmq
::
signaler_t
*
zmq
::
socket_base_t
::
get_signaler
()
...
...
@@ -599,16 +604,13 @@ zmq::session_t *zmq::socket_base_t::find_session (const blob_t &peer_identity_)
return
session
;
}
bool
zmq
::
socket_base_t
::
dezombify
()
void
zmq
::
socket_base_t
::
dezombify
()
{
zmq_assert
(
zombie
);
// Process any commands from other threads/sockets that may be available
// at the moment. Ultimately, socket will be destroyed.
process_commands
(
false
,
false
);
// TODO: ???
return
true
;
}
void
zmq
::
socket_base_t
::
process_commands
(
bool
block_
,
bool
throttle_
)
...
...
src/socket_base.hpp
View file @
936dbf95
...
...
@@ -85,8 +85,8 @@ namespace zmq
void
terminated
(
class
writer_t
*
pipe_
);
// This function should be called only on zombie sockets. It tries
// to deallocate the zombie.
Returns true if zombie is finally dead.
bool
dezombify
();
// to deallocate the zombie.
void
dezombify
();
protected
:
...
...
src/zmq.cpp
View file @
936dbf95
...
...
@@ -269,7 +269,7 @@ void *zmq_init (int io_threads_)
int
zmq_term
(
void
*
ctx_
)
{
int
rc
=
((
zmq
::
ctx_t
*
)
ctx_
)
->
term
();
int
rc
=
((
zmq
::
ctx_t
*
)
ctx_
)
->
term
inate
();
int
en
=
errno
;
if
(
!
ctx_
)
{
...
...
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