# include <algorithm>
# include <cassert>
# include <csignal>
# include <iostream>
# include <map>
# include <string>
typedef void ( * sighandler_t ) ( int sig ) ;
# include "cereal/services.h"
# include "msgq/impl_msgq.h"
# include "msgq/impl_zmq.h"
std : : atomic < bool > do_exit = false ;
static void set_do_exit ( int sig ) {
do_exit = true ;
}
void sigpipe_handler ( int sig ) {
assert ( sig = = SIGPIPE ) ;
std : : cout < < " SIGPIPE received " < < std : : endl ;
}
static std : : vector < std : : string > get_services ( std : : string whitelist_str , bool zmq_to_msgq ) {
std : : vector < std : : string > service_list ;
for ( const auto & it : services ) {
std : : string name = it . second . name ;
bool in_whitelist = whitelist_str . find ( name ) ! = std : : string : : npos ;
if ( name = = " plusFrame " | | name = = " uiLayoutState " | | ( zmq_to_msgq & & ! in_whitelist ) ) {
continue ;
}
service_list . push_back ( name ) ;
}
return service_list ;
}
int main ( int argc , char * * argv ) {
signal ( SIGPIPE , ( sighandler_t ) sigpipe_handler ) ;
signal ( SIGINT , ( sighandler_t ) set_do_exit ) ;
signal ( SIGTERM , ( sighandler_t ) set_do_exit ) ;
bool zmq_to_msgq = argc > 2 ;
std : : string ip = zmq_to_msgq ? argv [ 1 ] : " 127.0.0.1 " ;
std : : string whitelist_str = zmq_to_msgq ? std : : string ( argv [ 2 ] ) : " " ;
Poller * poller ;
Context * pub_context ;
Context * sub_context ;
if ( zmq_to_msgq ) { // republishes zmq debugging messages as msgq
poller = new ZMQPoller ( ) ;
pub_context = new MSGQContext ( ) ;
sub_context = new ZMQContext ( ) ;
} else {
poller = new MSGQPoller ( ) ;
pub_context = new ZMQContext ( ) ;
sub_context = new MSGQContext ( ) ;
}
std : : map < SubSocket * , PubSocket * > sub2pub ;
for ( auto endpoint : get_services ( whitelist_str , zmq_to_msgq ) ) {
PubSocket * pub_sock ;
SubSocket * sub_sock ;
if ( zmq_to_msgq ) {
pub_sock = new MSGQPubSocket ( ) ;
sub_sock = new ZMQSubSocket ( ) ;
} else {
pub_sock = new ZMQPubSocket ( ) ;
sub_sock = new MSGQSubSocket ( ) ;
}
pub_sock - > connect ( pub_context , endpoint ) ;
sub_sock - > connect ( sub_context , endpoint , ip , false ) ;
poller - > registerSocket ( sub_sock ) ;
sub2pub [ sub_sock ] = pub_sock ;
}
while ( ! do_exit ) {
for ( auto sub_sock : poller - > poll ( 100 ) ) {
Message * msg = sub_sock - > receive ( ) ;
if ( msg = = NULL ) continue ;
int ret ;
do {
ret = sub2pub [ sub_sock ] - > sendMessage ( msg ) ;
} while ( ret = = - 1 & & errno = = EINTR & & ! do_exit ) ;
assert ( ret > = 0 | | do_exit ) ;
delete msg ;
if ( do_exit ) break ;
}
}
return 0 ;
}