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
aebff623
Commit
aebff623
authored
Dec 23, 2009
by
Martin Sustrik
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ZMQII-28: Bidirectional introduction on TCP connection establishment
parent
b3bd4c15
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
387 additions
and
459 deletions
+387
-459
Makefile.am
src/Makefile.am
+3
-5
i_inout.hpp
src/i_inout.hpp
+4
-2
pgm_receiver.cpp
src/pgm_receiver.cpp
+1
-2
pgm_receiver.hpp
src/pgm_receiver.hpp
+1
-5
pgm_sender.cpp
src/pgm_sender.cpp
+1
-2
pgm_sender.hpp
src/pgm_sender.hpp
+1
-5
session.cpp
src/session.cpp
+41
-13
session.hpp
src/session.hpp
+18
-6
socket_base.cpp
src/socket_base.cpp
+58
-25
socket_base.hpp
src/socket_base.hpp
+17
-10
zmq_connecter.cpp
src/zmq_connecter.cpp
+8
-7
zmq_connecter.hpp
src/zmq_connecter.hpp
+4
-4
zmq_connecter_init.cpp
src/zmq_connecter_init.cpp
+0
-132
zmq_connecter_init.hpp
src/zmq_connecter_init.hpp
+0
-79
zmq_engine.cpp
src/zmq_engine.cpp
+1
-1
zmq_init.cpp
src/zmq_init.cpp
+195
-0
zmq_init.hpp
src/zmq_init.hpp
+31
-21
zmq_listener.cpp
src/zmq_listener.cpp
+3
-3
zmq_listener_init.cpp
src/zmq_listener_init.cpp
+0
-137
No files found.
src/Makefile.am
View file @
aebff623
...
...
@@ -115,12 +115,11 @@ libzmq_la_SOURCES = app_thread.hpp \
ypollset.hpp
\
yqueue.hpp
\
zmq_connecter.hpp
\
zmq_connecter_init.hpp
\
zmq_decoder.hpp
\
zmq_encoder.hpp
\
zmq_engine.hpp
\
zmq_init.hpp
\
zmq_listener.hpp
\
zmq_listener_init.hpp
\
app_thread.cpp
\
devpoll.cpp
\
dispatcher.cpp
\
...
...
@@ -161,12 +160,11 @@ libzmq_la_SOURCES = app_thread.hpp \
ypollset.cpp
\
zmq.cpp
\
zmq_connecter.cpp
\
zmq_connecter_init.cpp
\
zmq_decoder.cpp
\
zmq_encoder.cpp
\
zmq_engine.cpp
\
zmq_
listener
.cpp
\
zmq_listener
_init
.cpp
zmq_
init
.cpp
\
zmq_listener.cpp
libzmq_la_LDFLAGS
=
-version-info
@LTVER@ @LIBZMQ_EXTRA_LDFLAFS@
...
...
src/i_inout.hpp
View file @
aebff623
...
...
@@ -22,6 +22,8 @@
#include "../bindings/c/zmq.h"
#include "stdint.hpp"
namespace
zmq
{
...
...
@@ -47,8 +49,8 @@ namespace zmq
// Return pointer to the owning socket.
virtual
class
socket_base_t
*
get_owner
()
=
0
;
// Return
s the name of associated
session.
virtual
const
char
*
get_session_name
()
=
0
;
// Return
ordinal number of the
session.
virtual
uint64_t
get_ordinal
()
=
0
;
};
}
...
...
src/pgm_receiver.cpp
View file @
aebff623
...
...
@@ -37,11 +37,10 @@
#include "i_inout.hpp"
zmq
::
pgm_receiver_t
::
pgm_receiver_t
(
class
io_thread_t
*
parent_
,
const
options_t
&
options_
,
const
char
*
session_name_
)
:
const
options_t
&
options_
)
:
io_object_t
(
parent_
),
pgm_socket
(
true
,
options_
),
options
(
options_
),
session_name
(
session_name_
),
inout
(
NULL
)
{
}
...
...
src/pgm_receiver.hpp
View file @
aebff623
...
...
@@ -47,8 +47,7 @@ namespace zmq
// Creates gm_engine. Underlying PGM connection is initialised
// using network_ parameter.
pgm_receiver_t
(
class
io_thread_t
*
parent_
,
const
options_t
&
options_
,
const
char
*
session_name_
);
pgm_receiver_t
(
class
io_thread_t
*
parent_
,
const
options_t
&
options_
);
~
pgm_receiver_t
();
int
init
(
bool
udp_encapsulation_
,
const
char
*
network_
);
...
...
@@ -94,9 +93,6 @@ namespace zmq
// Socket options.
options_t
options
;
// Name of the session associated with the connecter.
std
::
string
session_name
;
// Parent session.
i_inout
*
inout
;
...
...
src/pgm_sender.cpp
View file @
aebff623
...
...
@@ -33,12 +33,11 @@
#include "wire.hpp"
zmq
::
pgm_sender_t
::
pgm_sender_t
(
io_thread_t
*
parent_
,
const
options_t
&
options_
,
const
char
*
session_name_
)
:
const
options_t
&
options_
)
:
io_object_t
(
parent_
),
encoder
(
0
,
false
),
pgm_socket
(
false
,
options_
),
options
(
options_
),
session_name
(
session_name_
),
inout
(
NULL
),
out_buffer
(
NULL
),
out_buffer_size
(
0
),
...
...
src/pgm_sender.hpp
View file @
aebff623
...
...
@@ -42,8 +42,7 @@ namespace zmq
{
public
:
pgm_sender_t
(
class
io_thread_t
*
parent_
,
const
options_t
&
options_
,
const
char
*
session_name_
);
pgm_sender_t
(
class
io_thread_t
*
parent_
,
const
options_t
&
options_
);
~
pgm_sender_t
();
int
init
(
bool
udp_encapsulation_
,
const
char
*
network_
);
...
...
@@ -74,9 +73,6 @@ namespace zmq
// Socket options.
options_t
options
;
// Name of the session associated with the connecter.
std
::
string
session_name
;
// Poll handle associated with PGM socket.
handle_t
handle
;
handle_t
uplink_handle
;
...
...
src/session.cpp
View file @
aebff623
...
...
@@ -25,16 +25,41 @@
#include "pipe.hpp"
zmq
::
session_t
::
session_t
(
object_t
*
parent_
,
socket_base_t
*
owner_
,
const
char
*
name_
,
const
options_t
&
options_
,
bool
reconnect
_
)
:
const
options_t
&
options
_
)
:
owned_t
(
parent_
,
owner_
),
in_pipe
(
NULL
),
active
(
true
),
out_pipe
(
NULL
),
engine
(
NULL
),
name
(
name_
),
options
(
options_
),
reconnect
(
reconnect_
)
options
(
options_
)
{
type
=
unnamed
;
// It's possible to register the session at this point as it will be
// searched for only on reconnect, i.e. no race condition (session found
// before it is plugged into it's I/O thread) is possible.
ordinal
=
owner
->
register_session
(
this
);
}
zmq
::
session_t
::
session_t
(
object_t
*
parent_
,
socket_base_t
*
owner_
,
const
options_t
&
options_
,
const
char
*
name_
)
:
owned_t
(
parent_
,
owner_
),
in_pipe
(
NULL
),
active
(
true
),
out_pipe
(
NULL
),
engine
(
NULL
),
options
(
options_
)
{
if
(
name_
)
{
type
=
named
;
name
=
name_
;
ordinal
=
0
;
}
else
{
type
=
transient
;
// TODO: Generate unique name here.
ordinal
=
0
;
}
}
zmq
::
session_t
::~
session_t
()
...
...
@@ -78,8 +103,8 @@ void zmq::session_t::detach (owned_t *reconnecter_)
// Engine is terminating itself. No need to deallocate it from here.
engine
=
NULL
;
//
In the case od anonymous connection, terminate the
session.
if
(
name
.
empty
()
)
//
Terminate transient
session.
if
(
type
==
transient
)
term
();
}
...
...
@@ -93,9 +118,11 @@ class zmq::socket_base_t *zmq::session_t::get_owner ()
return
owner
;
}
const
char
*
zmq
::
session_t
::
get_session_name
()
uint64_t
zmq
::
session_t
::
get_ordinal
()
{
return
name
.
c_str
();
zmq_assert
(
type
==
unnamed
);
zmq_assert
(
ordinal
);
return
ordinal
;
}
void
zmq
::
session_t
::
attach_pipes
(
class
reader_t
*
inpipe_
,
...
...
@@ -181,11 +208,12 @@ void zmq::session_t::process_plug ()
void
zmq
::
session_t
::
process_unplug
()
{
// Unregister the session from the socket.
if
(
!
name
.
empty
())
{
bool
ok
=
owner
->
unregister_session
(
name
.
c_str
());
zmq_assert
(
ok
);
}
// Unregister the session from the socket. There's nothing to do here
// for transient sessions.
if
(
type
==
unnamed
)
owner
->
unregister_session
(
ordinal
);
else
if
(
type
==
named
)
owner
->
unregister_session
(
name
.
c_str
());
// Ask associated pipes to terminate.
if
(
in_pipe
)
{
...
...
src/session.hpp
View file @
aebff623
...
...
@@ -34,8 +34,14 @@ namespace zmq
{
public
:
session_t
(
object_t
*
parent_
,
socket_base_t
*
owner_
,
const
char
*
name_
,
const
options_t
&
options_
,
bool
reconnect_
);
// Creates unnamed session.
session_t
(
object_t
*
parent_
,
socket_base_t
*
owner_
,
const
options_t
&
options_
);
// Creates named session. If name is NULL, transient session with
// auto-generated name is created.
session_t
(
object_t
*
parent_
,
socket_base_t
*
owner_
,
const
options_t
&
options_
,
const
char
*
name_
);
// i_inout interface implementation.
bool
read
(
::
zmq_msg_t
*
msg_
);
...
...
@@ -44,7 +50,7 @@ namespace zmq
void
detach
(
owned_t
*
reconnecter_
);
class
io_thread_t
*
get_io_thread
();
class
socket_base_t
*
get_owner
();
const
char
*
get_session_name
();
uint64_t
get_ordinal
();
// i_endpoint interface implementation.
void
attach_pipes
(
class
reader_t
*
inpipe_
,
class
writer_t
*
outpipe_
);
...
...
@@ -73,6 +79,15 @@ namespace zmq
struct
i_engine
*
engine
;
enum
{
transient
,
named
,
unnamed
}
type
;
// Ordinal of the session (if any).
uint64_t
ordinal
;
// The name of the session. One that is used to register it with
// socket-level repository of sessions.
std
::
string
name
;
...
...
@@ -80,9 +95,6 @@ namespace zmq
// Inherited socket options.
options_t
options
;
// If true, reconnection is required after connection breaks.
bool
reconnect
;
session_t
(
const
session_t
&
);
void
operator
=
(
const
session_t
&
);
};
...
...
src/socket_base.cpp
View file @
aebff623
...
...
@@ -32,7 +32,6 @@
#include "session.hpp"
#include "config.hpp"
#include "owned.hpp"
#include "uuid.hpp"
#include "pipe.hpp"
#include "err.hpp"
#include "platform.hpp"
...
...
@@ -46,7 +45,8 @@ zmq::socket_base_t::socket_base_t (app_thread_t *parent_) :
app_thread
(
parent_
),
shutting_down
(
false
),
sent_seqnum
(
0
),
processed_seqnum
(
0
)
processed_seqnum
(
0
),
next_ordinal
(
1
)
{
}
...
...
@@ -114,10 +114,6 @@ int zmq::socket_base_t::bind (const char *addr_)
int
zmq
::
socket_base_t
::
connect
(
const
char
*
addr_
)
{
// Generate a unique name for the session.
std
::
string
session_name
(
"#"
);
session_name
+=
uuid_t
().
to_string
();
// Parse addr_ string.
std
::
string
addr_type
;
std
::
string
addr_args
;
...
...
@@ -170,10 +166,10 @@ int zmq::socket_base_t::connect (const char *addr_)
return
0
;
}
// Create
the
session.
// Create
unnamed
session.
io_thread_t
*
io_thread
=
choose_io_thread
(
options
.
affinity
);
session_t
*
session
=
new
(
std
::
nothrow
)
session_t
(
io_thread
,
this
,
session_name
.
c_str
(),
options
,
true
);
session_t
*
session
=
new
(
std
::
nothrow
)
session_t
(
io_thread
,
this
,
options
);
zmq_assert
(
session
);
pipe_t
*
in_pipe
=
NULL
;
...
...
@@ -213,7 +209,7 @@ int zmq::socket_base_t::connect (const char *addr_)
// it is established.
zmq_connecter_t
*
connecter
=
new
(
std
::
nothrow
)
zmq_connecter_t
(
choose_io_thread
(
options
.
affinity
),
this
,
options
,
session
_name
.
c_str
(),
false
);
session
->
get_ordinal
(),
false
);
zmq_assert
(
connecter
);
int
rc
=
connecter
->
set_address
(
addr_args
.
c_str
());
if
(
rc
!=
0
)
{
...
...
@@ -245,8 +241,7 @@ int zmq::socket_base_t::connect (const char *addr_)
// PGM sender.
pgm_sender_t
*
pgm_sender
=
new
(
std
::
nothrow
)
pgm_sender_t
(
choose_io_thread
(
options
.
affinity
),
options
,
session_name
.
c_str
());
choose_io_thread
(
options
.
affinity
),
options
);
zmq_assert
(
pgm_sender
);
int
rc
=
pgm_sender
->
init
(
udp_encapsulation
,
addr_args
.
c_str
());
...
...
@@ -261,8 +256,7 @@ int zmq::socket_base_t::connect (const char *addr_)
// PGM receiver.
pgm_receiver_t
*
pgm_receiver
=
new
(
std
::
nothrow
)
pgm_receiver_t
(
choose_io_thread
(
options
.
affinity
),
options
,
session_name
.
c_str
());
choose_io_thread
(
options
.
affinity
),
options
);
zmq_assert
(
pgm_receiver
);
int
rc
=
pgm_receiver
->
init
(
udp_encapsulation
,
addr_args
.
c_str
());
...
...
@@ -408,7 +402,8 @@ int zmq::socket_base_t::close ()
// Check whether there are no session leaks.
sessions_sync
.
lock
();
zmq_assert
(
sessions
.
empty
());
zmq_assert
(
named_sessions
.
empty
());
zmq_assert
(
unnamed_sessions
.
empty
());
sessions_sync
.
unlock
();
delete
this
;
...
...
@@ -445,36 +440,74 @@ bool zmq::socket_base_t::register_session (const char *name_,
session_t
*
session_
)
{
sessions_sync
.
lock
();
bool
registered
=
sessions
.
insert
(
std
::
make_pair
(
name_
,
session_
)).
second
;
bool
registered
=
named_sessions
.
insert
(
std
::
make_pair
(
name_
,
session_
)).
second
;
sessions_sync
.
unlock
();
return
registered
;
}
bool
zmq
::
socket_base_t
::
unregister_session
(
const
char
*
name_
)
void
zmq
::
socket_base_t
::
unregister_session
(
const
char
*
name_
)
{
sessions_sync
.
lock
();
sessions_t
::
iterator
it
=
sessions
.
find
(
name_
);
bool
unregistered
=
(
it
!=
sessions
.
end
());
sessions
.
erase
(
it
);
named_sessions_t
::
iterator
it
=
named_
sessions
.
find
(
name_
);
zmq_assert
(
it
!=
named_
sessions
.
end
());
named_
sessions
.
erase
(
it
);
sessions_sync
.
unlock
();
return
unregistered
;
}
zmq
::
session_t
*
zmq
::
socket_base_t
::
find_session
(
const
char
*
name_
)
{
sessions_sync
.
lock
();
sessions_t
::
iterator
it
=
sessions
.
find
(
name_
);
if
(
it
==
sessions
.
end
())
{
named_sessions_t
::
iterator
it
=
named_sessions
.
find
(
name_
);
if
(
it
==
named_sessions
.
end
())
{
sessions_sync
.
unlock
();
return
NULL
;
}
session_t
*
session
=
it
->
second
;
// Prepare the session for subsequent attach command.
session
->
inc_seqnum
();
sessions_sync
.
unlock
();
return
session
;
}
uint64_t
zmq
::
socket_base_t
::
register_session
(
session_t
*
session_
)
{
sessions_sync
.
lock
();
uint64_t
ordinal
=
next_ordinal
;
next_ordinal
++
;
unnamed_sessions
.
insert
(
std
::
make_pair
(
ordinal
,
session_
)).
second
;
sessions_sync
.
unlock
();
return
ordinal
;
}
void
zmq
::
socket_base_t
::
unregister_session
(
uint64_t
ordinal_
)
{
sessions_sync
.
lock
();
unnamed_sessions_t
::
iterator
it
=
unnamed_sessions
.
find
(
ordinal_
);
zmq_assert
(
it
!=
unnamed_sessions
.
end
());
unnamed_sessions
.
erase
(
it
);
sessions_sync
.
unlock
();
}
zmq
::
session_t
*
zmq
::
socket_base_t
::
find_session
(
uint64_t
ordinal_
)
{
sessions_sync
.
lock
();
unnamed_sessions_t
::
iterator
it
=
unnamed_sessions
.
find
(
ordinal_
);
if
(
it
==
unnamed_sessions
.
end
())
{
sessions_sync
.
unlock
();
return
NULL
;
}
session_t
*
session
=
it
->
second
;
// Prepare the session for subsequent attach command.
it
->
second
->
inc_seqnum
();
session
->
inc_seqnum
();
sessions_sync
.
unlock
();
return
it
->
second
;
return
session
;
}
void
zmq
::
socket_base_t
::
kill
(
reader_t
*
pipe_
)
...
...
src/socket_base.hpp
View file @
aebff623
...
...
@@ -34,6 +34,7 @@
#include "options.hpp"
#include "stdint.hpp"
#include "atomic_counter.hpp"
#include "stdint.hpp"
namespace
zmq
{
...
...
@@ -74,9 +75,15 @@ namespace zmq
// commands as it is unacceptable to wait for the completion of the
// action till user application yields control of the application
// thread to 0MQ. Locking is used instead.
// There are two distinct types of sessions: those identified by name
// and those identified by ordinal number. Thus two sets of session
// management functions.
bool
register_session
(
const
char
*
name_
,
class
session_t
*
session_
);
bool
unregister_session
(
const
char
*
name_
);
void
unregister_session
(
const
char
*
name_
);
class
session_t
*
find_session
(
const
char
*
name_
);
uint64_t
register_session
(
class
session_t
*
session_
);
void
unregister_session
(
uint64_t
ordinal_
);
class
session_t
*
find_session
(
uint64_t
ordinal_
);
// i_endpoint interface implementation.
void
attach_pipes
(
class
reader_t
*
inpipe_
,
class
writer_t
*
outpipe_
);
...
...
@@ -144,15 +151,15 @@ namespace zmq
// Sequence number of the last command processed by this object.
uint64_t
processed_seqnum
;
// List
of existing sessions. This list is never referenced from within
//
the socket, instead it is used by I/O objects owned by the session.
//
As those objects can live in different threads, the access is
//
synchronised using 'sessions_sync'
mutex.
// Local sessions are those named by the local instance of 0MQ.
// Remote sessions are the sessions who's identities are provided by
// the remote party.
typedef
std
::
map
<
std
::
string
,
session_t
*>
sessions_t
;
sessions_t
sessions
;
// List
s of existing sessions. This lists are never referenced from
//
within the socket, instead they are used by I/O objects owned by
//
the socket. As those objects can live in different threads,
//
the access is synchronised by
mutex.
typedef
std
::
map
<
std
::
string
,
session_t
*>
named_sessions_t
;
named_sessions_t
named_sessions
;
typedef
std
::
map
<
uint64_t
,
session_t
*>
unnamed_sessions_t
;
unnamed_sessions_t
unnamed_sessions
;
uint64_t
next_ordinal
;
mutex_t
sessions_sync
;
socket_base_t
(
const
socket_base_t
&
);
...
...
src/zmq_connecter.cpp
View file @
aebff623
...
...
@@ -20,19 +20,20 @@
#include <new>
#include "zmq_connecter.hpp"
#include "zmq_connecter_init.hpp"
#include "zmq_engine.hpp"
#include "zmq_init.hpp"
#include "io_thread.hpp"
#include "err.hpp"
zmq
::
zmq_connecter_t
::
zmq_connecter_t
(
io_thread_t
*
parent_
,
socket_base_t
*
owner_
,
const
options_t
&
options_
,
const
char
*
session_name
_
,
bool
wait_
)
:
uint64_t
session_ordinal
_
,
bool
wait_
)
:
owned_t
(
parent_
,
owner_
),
io_object_t
(
parent_
),
handle_valid
(
false
),
wait
(
wait_
),
options
(
options
_
),
session_name
(
session_name
_
)
session_ordinal
(
session_ordinal
_
),
options
(
options
_
)
{
}
...
...
@@ -88,9 +89,9 @@ void zmq::zmq_connecter_t::out_event ()
}
// Create an init object.
io_thread_t
*
io_thread
=
choose_io_thread
(
options
.
affinity
);
zmq_connecter_init_t
*
init
=
new
(
std
::
nothrow
)
zmq_connecter_init_t
(
io_thread
,
owner
,
fd
,
options
,
session_name
.
c_str
(),
address
.
c_str
()
);
zmq_init_t
*
init
=
new
(
std
::
nothrow
)
zmq_init_t
(
choose_io_thread
(
options
.
affinity
),
owner
,
fd
,
options
,
true
,
address
.
c_str
(),
session_ordinal
);
zmq_assert
(
init
);
send_plug
(
init
);
send_own
(
owner
,
init
);
...
...
src/zmq_connecter.hpp
View file @
aebff623
...
...
@@ -36,7 +36,7 @@ namespace zmq
public
:
zmq_connecter_t
(
class
io_thread_t
*
parent_
,
socket_base_t
*
owner_
,
const
options_t
&
options_
,
const
char
*
session_name
_
,
bool
wait_
);
const
options_t
&
options_
,
uint64_t
session_ordinal
_
,
bool
wait_
);
~
zmq_connecter_t
();
// Set IP address to connect to.
...
...
@@ -69,12 +69,12 @@ namespace zmq
// If true, connecter is waiting a while before trying to connect.
bool
wait
;
// Ordinal of the session to attach to.
uint64_t
session_ordinal
;
// Associated socket options.
options_t
options
;
// Name of the session associated with the connecter.
std
::
string
session_name
;
// Address to connect to.
std
::
string
address
;
...
...
src/zmq_connecter_init.cpp
deleted
100644 → 0
View file @
b3bd4c15
/*
Copyright (c) 2007-2009 FastMQ Inc.
This file is part of 0MQ.
0MQ is free software; you can redistribute it and/or modify it under
the terms of the Lesser GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
0MQ is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Lesser GNU General Public License for more details.
You should have received a copy of the Lesser GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <new>
#include "zmq_connecter_init.hpp"
#include "zmq_connecter.hpp"
#include "io_thread.hpp"
#include "session.hpp"
#include "err.hpp"
zmq
::
zmq_connecter_init_t
::
zmq_connecter_init_t
(
io_thread_t
*
parent_
,
socket_base_t
*
owner_
,
fd_t
fd_
,
const
options_t
&
options_
,
const
char
*
session_name_
,
const
char
*
address_
)
:
owned_t
(
parent_
,
owner_
),
options
(
options_
),
session_name
(
session_name_
)
{
// Create associated engine object.
engine
=
new
(
std
::
nothrow
)
zmq_engine_t
(
parent_
,
fd_
,
options
,
true
,
address_
);
zmq_assert
(
engine
);
}
zmq
::
zmq_connecter_init_t
::~
zmq_connecter_init_t
()
{
if
(
engine
)
delete
engine
;
}
bool
zmq
::
zmq_connecter_init_t
::
read
(
::
zmq_msg_t
*
msg_
)
{
// Send identity.
int
rc
=
zmq_msg_init_size
(
msg_
,
options
.
identity
.
size
());
zmq_assert
(
rc
==
0
);
memcpy
(
zmq_msg_data
(
msg_
),
options
.
identity
.
c_str
(),
options
.
identity
.
size
());
// Initialisation is done at this point. Disconnect the engine from
// the init object.
engine
->
unplug
();
// Find the session associated with this connecter. If it doesn't exist
// drop the newly created connection. If it does, attach it to the
// connection.
session_t
*
session
=
NULL
;
if
(
!
session_name
.
empty
())
session
=
owner
->
find_session
(
session_name
.
c_str
());
if
(
!
session
)
{
// TODO:
// The socket is already closing. The session is already shut down,
// so no point in continuing with connecting. Shut the connection down.
zmq_assert
(
false
);
}
// No need to increment seqnum as it was alredy incremented above.
send_attach
(
session
,
engine
,
false
);
engine
=
NULL
;
// Destroy the init object.
term
();
return
true
;
}
bool
zmq
::
zmq_connecter_init_t
::
write
(
::
zmq_msg_t
*
msg_
)
{
return
false
;
}
void
zmq
::
zmq_connecter_init_t
::
flush
()
{
// We are not expecting any messages. No point in flushing.
}
void
zmq
::
zmq_connecter_init_t
::
detach
(
owned_t
*
reconnecter_
)
{
// Plug in the reconnecter object.
zmq_assert
(
reconnecter_
);
send_plug
(
reconnecter_
);
send_own
(
owner
,
reconnecter_
);
// This function is called by engine when disconnection occurs.
// The engine will destroy itself, so we just drop the pointer here and
// start termination of the init object.
engine
=
NULL
;
term
();
}
zmq
::
io_thread_t
*
zmq
::
zmq_connecter_init_t
::
get_io_thread
()
{
return
choose_io_thread
(
options
.
affinity
);
}
class
zmq
::
socket_base_t
*
zmq
::
zmq_connecter_init_t
::
get_owner
()
{
return
owner
;
}
const
char
*
zmq
::
zmq_connecter_init_t
::
get_session_name
()
{
return
session_name
.
c_str
();
}
void
zmq
::
zmq_connecter_init_t
::
process_plug
()
{
zmq_assert
(
engine
);
engine
->
plug
(
this
);
}
void
zmq
::
zmq_connecter_init_t
::
process_unplug
()
{
if
(
engine
)
engine
->
unplug
();
}
src/zmq_connecter_init.hpp
deleted
100644 → 0
View file @
b3bd4c15
/*
Copyright (c) 2007-2009 FastMQ Inc.
This file is part of 0MQ.
0MQ is free software; you can redistribute it and/or modify it under
the terms of the Lesser GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
0MQ is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Lesser GNU General Public License for more details.
You should have received a copy of the Lesser GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __ZMQ_ZMQ_CONNECTER_INIT_HPP_INCLUDED__
#define __ZMQ_ZMQ_CONNECTER_INIT_HPP_INCLUDED__
#include <string>
#include "i_inout.hpp"
#include "owned.hpp"
#include "zmq_engine.hpp"
#include "stdint.hpp"
#include "fd.hpp"
#include "options.hpp"
namespace
zmq
{
// The class handles initialisation phase of native 0MQ wire-level
// protocol on the connecting side of the connection.
class
zmq_connecter_init_t
:
public
owned_t
,
public
i_inout
{
public
:
zmq_connecter_init_t
(
class
io_thread_t
*
parent_
,
socket_base_t
*
owner_
,
fd_t
fd_
,
const
options_t
&
options
,
const
char
*
session_name_
,
const
char
*
address_
);
~
zmq_connecter_init_t
();
private
:
// i_inout interface implementation.
bool
read
(
::
zmq_msg_t
*
msg_
);
bool
write
(
::
zmq_msg_t
*
msg_
);
void
flush
();
void
detach
(
owned_t
*
reconnecter_
);
class
io_thread_t
*
get_io_thread
();
class
socket_base_t
*
get_owner
();
const
char
*
get_session_name
();
// Handlers for incoming commands.
void
process_plug
();
void
process_unplug
();
// Engine is created by zmq_connecter_init_t object. Once the
// initialisation phase is over it is passed to a session object,
// possibly running in a different I/O thread.
zmq_engine_t
*
engine
;
// Associated socket options.
options_t
options
;
// Name of the session to bind new connection to.
std
::
string
session_name
;
zmq_connecter_init_t
(
const
zmq_connecter_init_t
&
);
void
operator
=
(
const
zmq_connecter_init_t
&
);
};
}
#endif
src/zmq_engine.cpp
View file @
aebff623
...
...
@@ -159,7 +159,7 @@ void zmq::zmq_engine_t::error ()
// Ask it to wait for a while before reconnecting.
reconnecter
=
new
(
std
::
nothrow
)
zmq_connecter_t
(
inout
->
get_io_thread
(),
inout
->
get_owner
(),
options
,
inout
->
get_
session_name
(),
true
);
options
,
inout
->
get_
ordinal
(),
true
);
zmq_assert
(
reconnecter
);
reconnecter
->
set_address
(
address
.
c_str
());
}
...
...
src/zmq_init.cpp
0 → 100644
View file @
aebff623
/*
Copyright (c) 2007-2009 FastMQ Inc.
This file is part of 0MQ.
0MQ is free software; you can redistribute it and/or modify it under
the terms of the Lesser GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
0MQ is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Lesser GNU General Public License for more details.
You should have received a copy of the Lesser GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "zmq_init.hpp"
#include "zmq_engine.hpp"
#include "io_thread.hpp"
#include "session.hpp"
#include "err.hpp"
zmq
::
zmq_init_t
::
zmq_init_t
(
io_thread_t
*
parent_
,
socket_base_t
*
owner_
,
fd_t
fd_
,
const
options_t
&
options_
,
bool
reconnect_
,
const
char
*
address_
,
uint64_t
session_ordinal_
)
:
owned_t
(
parent_
,
owner_
),
sent
(
false
),
received
(
false
),
session_ordinal
(
session_ordinal_
),
options
(
options_
)
{
// Create the engine object for this connection.
engine
=
new
(
std
::
nothrow
)
zmq_engine_t
(
parent_
,
fd_
,
options
,
reconnect_
,
address_
);
zmq_assert
(
engine
);
}
zmq
::
zmq_init_t
::~
zmq_init_t
()
{
if
(
engine
)
delete
engine
;
}
bool
zmq
::
zmq_init_t
::
read
(
::
zmq_msg_t
*
msg_
)
{
// If the identity was already sent, do nothing.
if
(
sent
)
return
false
;
// Send the identity.
int
rc
=
zmq_msg_init_size
(
msg_
,
options
.
identity
.
size
());
zmq_assert
(
rc
==
0
);
memcpy
(
zmq_msg_data
(
msg_
),
options
.
identity
.
c_str
(),
options
.
identity
.
size
());
sent
=
true
;
// If initialisation is done, pass the engine to the session and
// destroy the init object.
finalise
();
return
true
;
}
bool
zmq
::
zmq_init_t
::
write
(
::
zmq_msg_t
*
msg_
)
{
// If identity was already received, we are not interested
// in subsequent messages.
if
(
received
)
return
false
;
// Retreieve the remote identity.
peer_identity
.
assign
((
const
char
*
)
zmq_msg_data
(
msg_
),
zmq_msg_size
(
msg_
));
received
=
true
;
return
true
;
}
void
zmq
::
zmq_init_t
::
flush
()
{
// Check if there's anything to flush.
if
(
!
received
)
return
;
// If initialisation is done, pass the engine to the session and
// destroy the init object.
finalise
();
}
void
zmq
::
zmq_init_t
::
detach
(
owned_t
*
reconnecter_
)
{
// This function is called by engine when disconnection occurs.
// If required, launch the reconnecter.
if
(
reconnecter_
)
{
send_plug
(
reconnecter_
);
send_own
(
owner
,
reconnecter_
);
}
// The engine will destroy itself, so let's just drop the pointer here and
// start termination of the init object.
engine
=
NULL
;
term
();
}
zmq
::
io_thread_t
*
zmq
::
zmq_init_t
::
get_io_thread
()
{
return
choose_io_thread
(
options
.
affinity
);
}
class
zmq
::
socket_base_t
*
zmq
::
zmq_init_t
::
get_owner
()
{
return
owner
;
}
uint64_t
zmq
::
zmq_init_t
::
get_ordinal
()
{
zmq_assert
(
false
);
}
void
zmq
::
zmq_init_t
::
process_plug
()
{
zmq_assert
(
engine
);
engine
->
plug
(
this
);
}
void
zmq
::
zmq_init_t
::
process_unplug
()
{
if
(
engine
)
engine
->
unplug
();
}
void
zmq
::
zmq_init_t
::
finalise
()
{
if
(
sent
&&
received
)
{
// Disconnect the engine from the init object.
engine
->
unplug
();
session_t
*
session
=
NULL
;
// If we have the session ordinal, let's use it to find the session.
// If it is not found, it means socket is already being shut down
// and the session have been deallocated.
// TODO: We should check whether the name of the peer haven't changed
// upon reconnection.
if
(
session_ordinal
)
{
session
=
owner
->
find_session
(
session_ordinal
);
if
(
!
session
)
{
term
();
return
;
}
}
// If the peer has a unique name, find the associated session. If it
// doesn't exist, create it.
else
if
(
!
peer_identity
.
empty
())
{
session
=
owner
->
find_session
(
peer_identity
.
c_str
());
if
(
!
session
)
{
session
=
new
(
std
::
nothrow
)
session_t
(
choose_io_thread
(
options
.
affinity
),
owner
,
options
,
peer_identity
.
c_str
());
zmq_assert
(
session
);
send_plug
(
session
);
send_own
(
owner
,
session
);
// Reserve a sequence number for following 'attach' command.
session
->
inc_seqnum
();
}
}
// If the other party has no specific identity, let's create a
// transient session.
else
{
session
=
new
(
std
::
nothrow
)
session_t
(
choose_io_thread
(
options
.
affinity
),
owner
,
options
,
NULL
);
zmq_assert
(
session
);
send_plug
(
session
);
send_own
(
owner
,
session
);
// Reserve a sequence number for following 'attach' command.
session
->
inc_seqnum
();
}
// No need to increment seqnum as it was laready incremented above.
send_attach
(
session
,
engine
,
false
);
// Destroy the init object.
engine
=
NULL
;
term
();
}
}
src/zmq_
listener_
init.hpp
→
src/zmq_init.hpp
View file @
aebff623
...
...
@@ -17,34 +17,37 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __ZMQ_ZMQ_
LISTENER_
INIT_HPP_INCLUDED__
#define __ZMQ_ZMQ_
LISTENER_
INIT_HPP_INCLUDED__
#ifndef __ZMQ_ZMQ_INIT_HPP_INCLUDED__
#define __ZMQ_ZMQ_INIT_HPP_INCLUDED__
#include <string>
#include "i_inout.hpp"
#include "i_engine.hpp"
#include "owned.hpp"
#include "zmq_engine.hpp"
#include "stdint.hpp"
#include "fd.hpp"
#include "stdint.hpp"
#include "options.hpp"
#include "stdint.hpp"
namespace
zmq
{
// The class handles initialisation phase of native 0MQ wire-level
// protocol on the listening side of the connection.
// The class handles initialisation phase of 0MQ wire-level protocol.
class
zmq_
listener_
init_t
:
public
owned_t
,
public
i_inout
class
zmq_init_t
:
public
owned_t
,
public
i_inout
{
public
:
zmq_listener_init_t
(
class
io_thread_t
*
parent_
,
socket_base_t
*
owner_
,
fd_t
fd_
,
const
options_t
&
options
);
~
zmq_listener_init_t
();
zmq_init_t
(
class
io_thread_t
*
parent_
,
socket_base_t
*
owner_
,
fd_t
fd_
,
const
options_t
&
options_
,
bool
reconnect_
,
const
char
*
address_
,
uint64_t
session_ordinal_
);
~
zmq_init_t
();
private
:
void
finalise
();
// i_inout interface implementation.
bool
read
(
::
zmq_msg_t
*
msg_
);
bool
write
(
::
zmq_msg_t
*
msg_
);
...
...
@@ -52,26 +55,33 @@ namespace zmq
void
detach
(
owned_t
*
reconnecter_
);
class
io_thread_t
*
get_io_thread
();
class
socket_base_t
*
get_owner
();
const
char
*
get_session_name
();
uint64_t
get_ordinal
();
// Handlers for incoming commands.
void
process_plug
();
void
process_unplug
();
// Engine is created by zmq_listener_init_t object. Once the
// initialisation phase is over it is passed to a session object,
// possibly running in a different I/O thread.
zmq_engine_t
*
engine
;
// Associated wite-protocol engine.
i_engine
*
engine
;
//
Associated socket options
.
options_t
options
;
//
True if our own identity was already sent to the peer
.
bool
sent
;
// Indetity on the other end of the connection.
bool
has_peer_identity
;
// True if peer's identity was already received.
bool
received
;
// Identity of the peer socket.
std
::
string
peer_identity
;
zmq_listener_init_t
(
const
zmq_listener_init_t
&
);
void
operator
=
(
const
zmq_listener_init_t
&
);
// TCP connecter creates session before the name of the peer is known.
// Thus we know only its ordinal number.
uint64_t
session_ordinal
;
// Associated socket options.
options_t
options
;
zmq_init_t
(
const
zmq_init_t
&
);
void
operator
=
(
const
zmq_init_t
&
);
};
}
...
...
src/zmq_listener.cpp
View file @
aebff623
...
...
@@ -20,7 +20,7 @@
#include <new>
#include "zmq_listener.hpp"
#include "zmq_
listener_
init.hpp"
#include "zmq_init.hpp"
#include "io_thread.hpp"
#include "err.hpp"
...
...
@@ -64,8 +64,8 @@ void zmq::zmq_listener_t::in_event ()
// Create an init object.
io_thread_t
*
io_thread
=
choose_io_thread
(
options
.
affinity
);
zmq_
listener_init_t
*
init
=
new
(
std
::
nothrow
)
zmq_listener
_init_t
(
io_thread
,
owner
,
fd
,
options
);
zmq_
init_t
*
init
=
new
(
std
::
nothrow
)
zmq
_init_t
(
io_thread
,
owner
,
fd
,
options
,
false
,
NULL
,
0
);
zmq_assert
(
init
);
send_plug
(
init
);
send_own
(
owner
,
init
);
...
...
src/zmq_listener_init.cpp
deleted
100644 → 0
View file @
b3bd4c15
/*
Copyright (c) 2007-2009 FastMQ Inc.
This file is part of 0MQ.
0MQ is free software; you can redistribute it and/or modify it under
the terms of the Lesser GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
0MQ is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Lesser GNU General Public License for more details.
You should have received a copy of the Lesser GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <new>
#include "zmq_listener_init.hpp"
#include "io_thread.hpp"
#include "session.hpp"
#include "err.hpp"
zmq
::
zmq_listener_init_t
::
zmq_listener_init_t
(
io_thread_t
*
parent_
,
socket_base_t
*
owner_
,
fd_t
fd_
,
const
options_t
&
options_
)
:
owned_t
(
parent_
,
owner_
),
options
(
options_
),
has_peer_identity
(
false
)
{
// Create associated engine object.
engine
=
new
(
std
::
nothrow
)
zmq_engine_t
(
parent_
,
fd_
,
options
,
false
,
NULL
);
zmq_assert
(
engine
);
}
zmq
::
zmq_listener_init_t
::~
zmq_listener_init_t
()
{
if
(
engine
)
delete
engine
;
}
bool
zmq
::
zmq_listener_init_t
::
read
(
::
zmq_msg_t
*
msg_
)
{
return
false
;
}
bool
zmq
::
zmq_listener_init_t
::
write
(
::
zmq_msg_t
*
msg_
)
{
// Once we've got peer's identity we aren't interested in subsequent
// messages.
if
(
has_peer_identity
)
return
false
;
// Retreieve the remote identity. We'll use it as a local session name.
has_peer_identity
=
true
;
peer_identity
.
assign
((
const
char
*
)
zmq_msg_data
(
msg_
),
zmq_msg_size
(
msg_
));
return
true
;
}
void
zmq
::
zmq_listener_init_t
::
flush
()
{
if
(
!
has_peer_identity
)
return
;
// Initialisation is done. Disconnect the engine from the init object.
engine
->
unplug
();
// Have a look whether the session already exists. If it does, attach it
// to the engine. If it doesn't create it first.
session_t
*
session
=
NULL
;
if
(
!
peer_identity
.
empty
())
session
=
owner
->
find_session
(
peer_identity
.
c_str
());
if
(
!
session
)
{
io_thread_t
*
io_thread
=
choose_io_thread
(
options
.
affinity
);
session
=
new
(
std
::
nothrow
)
session_t
(
io_thread
,
owner
,
peer_identity
.
c_str
(),
options
,
false
);
zmq_assert
(
session
);
send_plug
(
session
);
send_own
(
owner
,
session
);
// Reserve a sequence number for following 'attach' command.
session
->
inc_seqnum
();
}
// No need to increment seqnum as it was laready incremented above.
send_attach
(
session
,
engine
,
false
);
engine
=
NULL
;
// Destroy the init object.
term
();
}
void
zmq
::
zmq_listener_init_t
::
detach
(
owned_t
*
reconnecter_
)
{
// On the listening side of the connection we are never reconnecting.
zmq_assert
(
reconnecter_
==
NULL
);
// This function is called by engine when disconnection occurs.
// The engine will destroy itself, so we just drop the pointer here and
// start termination of the init object.
engine
=
NULL
;
term
();
}
zmq
::
io_thread_t
*
zmq
::
zmq_listener_init_t
::
get_io_thread
()
{
return
choose_io_thread
(
options
.
affinity
);
}
class
zmq
::
socket_base_t
*
zmq
::
zmq_listener_init_t
::
get_owner
()
{
return
owner
;
}
const
char
*
zmq
::
zmq_listener_init_t
::
get_session_name
()
{
zmq_assert
(
false
);
return
NULL
;
}
void
zmq
::
zmq_listener_init_t
::
process_plug
()
{
zmq_assert
(
engine
);
engine
->
plug
(
this
);
}
void
zmq
::
zmq_listener_init_t
::
process_unplug
()
{
if
(
engine
)
engine
->
unplug
();
}
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