From 879eaf77babef13084b95ef170742958d90389b6 Mon Sep 17 00:00:00 2001 From: fcolin Date: Mon, 6 Jul 2009 10:39:28 +0000 Subject: ajout IvyChangeMsg correction pb latence TCP_NODELAY --- Ivy/BufferedSocket.cxx | 19 ++- Ivy/Ivy.cxx | 26 ++++ Ivy/Ivy.h | 1 + Ivy/Ivy.vcproj | 4 +- Ivy/IvyApplication.cxx | 2 +- Ivy/IvyBinding.cxx | 374 ++++++++++++++++++++++++------------------------- Ivy/IvyBinding.h | 3 + Ivy/IvyStdAfx.h | 27 +--- Ivy/ThreadedSocket.cxx | 15 +- 9 files changed, 254 insertions(+), 217 deletions(-) diff --git a/Ivy/BufferedSocket.cxx b/Ivy/BufferedSocket.cxx index 1a11c56..fcf90c6 100644 --- a/Ivy/BufferedSocket.cxx +++ b/Ivy/BufferedSocket.cxx @@ -163,6 +163,23 @@ void CBufferedSocket::Send ( const char * data ) // if ( connected ) // { bool ok = SignalWriter(); - if ( !ok ) TRACE( "CBufferedSocket::SignalWriter Error %d\n", this->GetLastError()); + if ( !ok ) + { + char* lpMsgBuf; + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + this->GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &lpMsgBuf, + 0, + NULL ); + lpMsgBuf[strlen(lpMsgBuf) -2] = '\0'; // remove last \n + TRACE( "CBufferedSocket::SignalWriter Error %s\n",lpMsgBuf ); + // Free the buffer. + LocalFree( lpMsgBuf ); + } // } } diff --git a/Ivy/Ivy.cxx b/Ivy/Ivy.cxx index 4564c6f..16b76b1 100644 --- a/Ivy/Ivy.cxx +++ b/Ivy/Ivy.cxx @@ -204,6 +204,28 @@ void Ivy::UnbindMsg(int id) } +void Ivy::ChangeBindMsg(int id, const char *regexp, ...) +{ + char buffer[4096]; + char buffer2[8192]; + va_list args; + + va_start( args, regexp ); /* Initialize variable arguments. */ + _vsnprintf_s( buffer, sizeof(buffer), sizeof(buffer)-1, regexp, args ); + va_end( args); + + SubstituteInterval( buffer, buffer2, sizeof( buffer2 ) ); + regexp_out[ id ] = buffer2; + /* send to already connected */ + IvyApplicationList::iterator iter; + for ( iter = applications.begin() ; iter != applications.end() ; ++iter ) + { + IvyApplication *app = *iter; + app->SendMsg(IvyApplication::AddRegexp, id, buffer2 ); + } + +} + void Ivy::BindDirectMsg(IvyDirectMessageCallback *callback) { direct_callback = callback; @@ -230,6 +252,10 @@ void Ivy::AddApplication(IvyApplication *app) } applications.push_back( app ); LeaveCriticalSection( &m_application_cs ); + // put the socket in NOdelay , disable Nagle's Algorithm + // we want Ivy Send message Immediately + int flag=1; + int err = app->SetSockOpt( TCP_NODELAY, &flag, sizeof(flag) ); SendSubscriptions( app ); } void Ivy::RemoveApplication(IvyApplication * app) diff --git a/Ivy/Ivy.h b/Ivy/Ivy.h index cf90bdd..7a97947 100644 --- a/Ivy/Ivy.h +++ b/Ivy/Ivy.h @@ -109,6 +109,7 @@ public: int BindMsg( const char *regexp, IvyMessageCallback *cb ); int BindMsg( IvyMessageCallback *cb, const char *regexp, ... ); void UnbindMsg( int id ); + void ChangeBindMsg( int id, const char *regexp, ... ); Ivy( const char *name, const char* ready, IvyApplicationCallback *callback, bool Synchronous = true ); void start(const char *domain); void stop(); diff --git a/Ivy/Ivy.vcproj b/Ivy/Ivy.vcproj index 203b3ee..9c765fb 100644 --- a/Ivy/Ivy.vcproj +++ b/Ivy/Ivy.vcproj @@ -79,7 +79,7 @@ /> - * - * $Id: ivybind.c,v 1.9.2.7 2006/06/01 12:07:17 bustico Exp $ - * - * Please refer to file version.h for the - * copyright notice regarding this software - */ -/* Module de gestion de la syntaxe des messages Ivy */ -#include "IvyStdAfx.h" - -#include "IvyBinding.h" - -static int err_offset; - -#ifdef USE_PCRE - static const char *err_buf; -#else /* we don't USE_PCRE */ -static ivy::string err_buf; -#endif /* USE_PCRE */ - -/* classes de messages emis par l'application utilise pour le filtrage */ -static int messages_classes_count = 0; -static const char **messages_classes = 0; -/* regexp d'extraction du mot clef des regexp client pour le filtrage des regexp , ca va c'est clair ??? */ -static IvyBinding token_extract; - -IvyBinding::IvyBinding() -{ - nb_match = 0; -#ifdef USE_PCRE - regexp = NULL; - inspect = NULL; - ovector = NULL; - -#else /* we don't USE_PCRE */ - regexp = NULL; -#endif /* USE_PCRE */ - -} -IvyBinding::~IvyBinding() -{ -#ifdef USE_PCRE - if (inspect!=NULL) - pcre_free(inspect); - if (regexp!=NULL) - pcre_free(regexp); - if ( ovector != NULL ) - delete [] ovector; -#else /* we don't USE_PCRE */ - delete regexp; -#endif /* USE_PCRE */ -} -bool IvyBinding::Compile( const char * expression, int *erroffset, const char **errmessage ) -{ - int capture_count = 0; - bool compile = false; -#ifdef USE_PCRE - regexp = pcre_compile(expression, PCRE_CASELESS, &err_buf, &err_offset, NULL); - if ( regexp != NULL ) - { - this->inspect = pcre_study(regexp,0,&err_buf); - if (err_buf!=NULL) - { - printf("Error studying %s, message: %s\n",expression,err_buf); - } - pcre_fullinfo( regexp, inspect, PCRE_INFO_CAPTURECOUNT, &capture_count ); - if ( ovector != NULL ) - delete [] ovector; - // + 1 pour la capture totale - ovectorsize = (capture_count+1) * 3; - ovector = new int[ovectorsize]; - compile = true; - } - else - { - *erroffset = err_offset; - *errmessage = err_buf; - printf("Error compiling '%s', %s\n", expression, err_buf); - } -#else /* we don't USE_PCRE */ - regexp = new Regexp( expression, false ); - if ( regexp->CompiledOK() ) - { - compile = true; - } - else - { - err_buf = regexp->GetErrorString(); - *erroffset = err_offset; - *errmessage = err_buf.c_str(); - printf("Error compiling '%s', %s\n", expression, err_buf); - } -#endif /* USE_PCRE */ - return compile; -} - - -int IvyBinding::Exec( const char * message ) -{ -#ifdef USE_PCRE - - nb_match = pcre_exec( - regexp, - inspect, - message, - strlen(message), - 0, /* debut */ - 0, /* no other regexp option */ - ovector, - ovectorsize); - if (nb_match<1) return 0; /* no match */ -#else /* we don't USE_PCRE */ - if ( !regexp->Match( message ) ) - return 0; - nb_match = regexp->SubStrings()+1; // +1 first arg is wall string -#endif /* USE_PCRE */ - return nb_match; -} - -void IvyBinding::Match( const char *message, int argnum, int *arglen, const char **arg) -{ -#ifdef USE_PCRE - - *arglen = ovector[2*argnum+1]- ovector[2*argnum]; - *arg = message + ovector[2*argnum]; -#else /* we don't USE_PCRE */ - - - *arglen = regexp->SubLength(argnum); - *arg = message + regexp->SubStart(argnum); - -#endif /* USE_PCRE */ - -} - -//filter Expression Bind -void IvyBinding::SetFilter( int argc, const char **argv) -{ - const char *errbuf; - int erroffset; - - messages_classes_count = argc; - messages_classes = argv; - /* compile the token extraction regexp */ - - if ( !token_extract.Compile("^\\^([a-zA-Z_0-9-]+).*", & erroffset, & errbuf) ) - { - printf("Error compiling Token Extract regexp: %s\n", errbuf); - } -} - -int IvyBinding::Filter(const char *expression) -{ - int i; - int err; - int regexp_ok = 1; /* accepte tout par default */ - int tokenlen; - const char *token; - - if ( *expression =='^' && messages_classes_count !=0 ) - { - regexp_ok = 0; - - /* extract token */ - err = token_extract.Exec( expression ); - if ( err < 1 ) return 1; - token_extract.Match( expression , 1, &tokenlen, &token ); - for ( i = 0 ; i < messages_classes_count; i++ ) - { - if (strncmp( messages_classes[i], token, tokenlen ) == 0) { - return 1; } - // else { - //printf ("DBG> %s eliminé [%s]\n", token, expression); - //} - } - } - return regexp_ok; -} +/* + * Ivy, C++ interface + * + * Copyright (C) 1997-2000 + * Centre d'Études de la Navigation Aérienne + * + * Bind syntax for extracting message comtent + * using regexp or other + * + * Authors: François-Régis Colin + * + * $Id: ivybind.c,v 1.9.2.7 2006/06/01 12:07:17 bustico Exp $ + * + * Please refer to file version.h for the + * copyright notice regarding this software + */ +/* Module de gestion de la syntaxe des messages Ivy */ +#include "IvyStdAfx.h" + +#include "IvyBinding.h" + +static int err_offset; + +#ifdef USE_PCRE + static const char *err_buf; +#else /* we don't USE_PCRE */ +static ivy::string err_buf; +#endif /* USE_PCRE */ + +/* classes de messages emis par l'application utilise pour le filtrage */ +static int messages_classes_count = 0; +static const char **messages_classes = 0; +/* regexp d'extraction du mot clef des regexp client pour le filtrage des regexp , ca va c'est clair ??? */ +static IvyBinding token_extract; + +IvyBinding::IvyBinding() +{ + nb_match = 0; +#ifdef USE_PCRE + regexp = NULL; + inspect = NULL; + ovector = NULL; + +#else /* we don't USE_PCRE */ + regexp = NULL; +#endif /* USE_PCRE */ + +} +IvyBinding::~IvyBinding() +{ +#ifdef USE_PCRE + if (inspect!=NULL) + pcre_free(inspect); + if (regexp!=NULL) + pcre_free(regexp); + if ( ovector != NULL ) + delete [] ovector; +#else /* we don't USE_PCRE */ + delete regexp; +#endif /* USE_PCRE */ +} +bool IvyBinding::Compile( const char * expression, int *erroffset, const char **errmessage ) +{ + int capture_count = 0; + bool compile = false; +#ifdef USE_PCRE + regexp = pcre_compile(expression, PCRE_CASELESS, &err_buf, &err_offset, NULL); + if ( regexp != NULL ) + { + this->inspect = pcre_study(regexp,0,&err_buf); + if (err_buf!=NULL) + { + printf("Error studying %s, message: %s\n",expression,err_buf); + } + pcre_fullinfo( regexp, inspect, PCRE_INFO_CAPTURECOUNT, &capture_count ); + if ( ovector != NULL ) + delete [] ovector; + // + 1 pour la capture totale + ovectorsize = (capture_count+1) * 3; + ovector = new int[ovectorsize]; + compile = true; + } + else + { + *erroffset = err_offset; + *errmessage = err_buf; + printf("Error compiling '%s', %s\n", expression, err_buf); + } +#else /* we don't USE_PCRE */ + regexp = new Regexp( expression, false ); + if ( regexp->CompiledOK() ) + { + compile = true; + } + else + { + err_buf = regexp->GetErrorString(); + *erroffset = err_offset; + *errmessage = err_buf.c_str(); + printf("Error compiling '%s', %s\n", expression, err_buf); + } +#endif /* USE_PCRE */ + return compile; +} + + +int IvyBinding::Exec( const char * message ) +{ +#ifdef USE_PCRE + + nb_match = pcre_exec( + regexp, + inspect, + message, + strlen(message), + 0, /* debut */ + 0, /* no other regexp option */ + ovector, + ovectorsize); + if (nb_match<1) return 0; /* no match */ +#else /* we don't USE_PCRE */ + if ( !regexp->Match( message ) ) + return 0; + nb_match = regexp->SubStrings()+1; // +1 first arg is wall string +#endif /* USE_PCRE */ + return nb_match; +} + +void IvyBinding::Match( const char *message, int argnum, int *arglen, const char **arg) +{ +#ifdef USE_PCRE + + *arglen = ovector[2*argnum+1]- ovector[2*argnum]; + *arg = message + ovector[2*argnum]; +#else /* we don't USE_PCRE */ + + + *arglen = regexp->SubLength(argnum); + *arg = message + regexp->SubStart(argnum); + +#endif /* USE_PCRE */ + +} + +//filter Expression Bind +void IvyBinding::SetFilter( int argc, const char **argv) +{ + const char *errbuf; + int erroffset; + + messages_classes_count = argc; + messages_classes = argv; + /* compile the token extraction regexp */ + + if ( !token_extract.Compile("^\\^([a-zA-Z_0-9-]+).*", & erroffset, & errbuf) ) + { + printf("Error compiling Token Extract regexp: %s\n", errbuf); + } +} + +int IvyBinding::Filter(const char *expression) +{ + int i; + int err; + int regexp_ok = 1; /* accepte tout par default */ + int tokenlen; + const char *token; + + if ( *expression =='^' && messages_classes_count !=0 ) + { + regexp_ok = 0; + + /* extract token */ + err = token_extract.Exec( expression ); + if ( err < 1 ) return 1; + token_extract.Match( expression , 1, &tokenlen, &token ); + for ( i = 0 ; i < messages_classes_count; i++ ) + { + if (strncmp( messages_classes[i], token, tokenlen ) == 0) { + return 1; } + // else { + //printf ("DBG> %s eliminé [%s]\n", token, expression); + //} + } + } + return regexp_ok; +} diff --git a/Ivy/IvyBinding.h b/Ivy/IvyBinding.h index 4354e55..38d6533 100644 --- a/Ivy/IvyBinding.h +++ b/Ivy/IvyBinding.h @@ -45,6 +45,9 @@ public: private: #ifdef USE_PCRE +#ifdef _DEBUG + std::string expression_string; +#endif pcre *regexp; pcre_extra *inspect; int ovectorsize; diff --git a/Ivy/IvyStdAfx.h b/Ivy/IvyStdAfx.h index 58a16bb..f41104b 100644 --- a/Ivy/IvyStdAfx.h +++ b/Ivy/IvyStdAfx.h @@ -11,35 +11,14 @@ #pragma warning( disable : 4251 ) // 'm' : class 'X' needs to have dll-interface to be used by clients of class 'Y' #endif -#include - +#include +#include #include #include #include //#include -#ifdef _WINSOCK2API_ -// Some definition missing from winsock2 -/* - * Options for use with [gs]etsockopt at the IP level. - */ -#define IP_OPTIONS 1 /* set/get IP per-packet options */ -#define IP_MULTICAST_IF 2 /* set/get IP multicast interface */ -#define IP_MULTICAST_TTL 3 /* set/get IP multicast timetolive */ -#define IP_MULTICAST_LOOP 4 /* set/get IP multicast loopback */ -#define IP_ADD_MEMBERSHIP 5 /* add an IP group membership */ -#define IP_DROP_MEMBERSHIP 6 /* drop an IP group membership */ -#define IP_TTL 7 /* set/get IP Time To Live */ -#define IP_TOS 8 /* set/get IP Type Of Service */ -#define IP_DONTFRAGMENT 9 /* set/get IP Don't Fragment flag */ -/* - * Argument structure for IP_ADD_MEMBERSHIP and IP_DROP_MEMBERSHIP. - */ -struct ip_mreq { - struct in_addr imr_multiaddr; /* IP multicast address of group */ - struct in_addr imr_interface; /* local IP address of interface */ -}; -#endif + #ifndef IN_CLASSD #define IN_CLASSD(i) (((long)(i) & 0xf0000000) == 0xe0000000) diff --git a/Ivy/ThreadedSocket.cxx b/Ivy/ThreadedSocket.cxx index ee1e03b..7d43bb5 100644 --- a/Ivy/ThreadedSocket.cxx +++ b/Ivy/ThreadedSocket.cxx @@ -304,8 +304,19 @@ int CThreadedSocket::AddMember( const char * lpszHostAddress ) } if ( IN_CLASSD( htonl(imr.imr_multiaddr.s_addr) ) ) { - SetSockOpt( IP_MULTICAST_TTL, &multicast_ttl, sizeof( multicast_ttl ), IPPROTO_IP ); - SetSockOpt( IP_ADD_MEMBERSHIP, &imr, sizeof( imr ), IPPROTO_IP ); + int err; + err = SetSockOpt( IP_MULTICAST_TTL, &multicast_ttl, sizeof( multicast_ttl ), IPPROTO_IP ); + if ( err != 0 ) + { + TRACE("CThreadedSocket::AddMember IP_MULTICAST_TTL error %d\n", GetLastError()); + return err; + } + err = SetSockOpt( IP_ADD_MEMBERSHIP, &imr, sizeof( imr ), IPPROTO_IP ); + if ( err != 0 ) + { + TRACE("CThreadedSocket::AddMember IP_ADD_MEMBERSHIP error %d\n", GetLastError()); + return err; + } } return 0; } -- cgit v1.1