From 00e97f3decde46e85fba871a20aa79e27cb679e3 Mon Sep 17 00:00:00 2001 From: fcolin Date: Thu, 8 Oct 2009 13:07:04 +0000 Subject: correction des bug connexion concurrente correction sur le ready message attente des deux endRegexp --- Ivy/Ivy.cxx | 10 +++++----- Ivy/Ivy.h | 2 +- Ivy/Ivy.vcproj | 3 +-- Ivy/IvyApplication.cxx | 49 ++++++++++++++++++++++++++++++++++++++++--------- Ivy/IvyApplication.h | 8 ++++++-- Ivy/ThreadedSocket.cxx | 22 ++++++++++++++++++++++ Ivy/ThreadedSocket.h | 4 ++++ 7 files changed, 79 insertions(+), 19 deletions(-) (limited to 'Ivy') diff --git a/Ivy/Ivy.cxx b/Ivy/Ivy.cxx index 16b76b1..fa1021d 100644 --- a/Ivy/Ivy.cxx +++ b/Ivy/Ivy.cxx @@ -284,7 +284,7 @@ void Ivy::SendSubscriptions(IvyApplication *app) app->SendMsg( IvyApplication::AddRegexp, id, regexp.c_str()); } app->SendMsg( IvyApplication::EndRegexp, 0); - + app->SendReadyToPeer(); } @@ -406,19 +406,19 @@ void Ivy::SetFilter(int argc, const char **argv ) IvyBinding::SetFilter(argc, argv ); } -bool Ivy::CheckConnected(IvyApplication * app) +IvyApplication * Ivy::CheckConnected(IvyApplication * app) { if (app->remoteService == 0) /* old application dont check */ - return false; + return 0; /* check to see if app already connected */ IvyApplicationList::iterator iter; for ( iter = applications.begin() ; iter != applications.end() ; ++iter ) { IvyApplication *application = *iter; if ( application != app && application->SameApplication(app)) - return true; + return application; } - return false; + return 0; } void Ivy::SubstituteInterval (const char *src, char *dst, size_t dst_len) { diff --git a/Ivy/Ivy.h b/Ivy/Ivy.h index 7a97947..7c51f0b 100644 --- a/Ivy/Ivy.h +++ b/Ivy/Ivy.h @@ -79,7 +79,7 @@ protected: void AddApplication( IvyApplication *app ); void RemoveApplication( IvyApplication *app); - bool CheckConnected( IvyApplication *app ); + IvyApplication *CheckConnected( IvyApplication *app ); void CallApplicationConnectedCallback( IvyApplication *app ); void CallApplicationDisconnectedCallback( IvyApplication *app ); void CallBindingAddCallback(IvyApplication * app, int id, const char * regexp); diff --git a/Ivy/Ivy.vcproj b/Ivy/Ivy.vcproj index afbd6b5..386e29e 100644 --- a/Ivy/Ivy.vcproj +++ b/Ivy/Ivy.vcproj @@ -332,7 +332,6 @@ PrecompiledHeaderThrough="IvyStdAfx.h" WarningLevel="3" SuppressStartupBanner="true" - Detect64BitPortabilityProblems="true" /> diff --git a/Ivy/IvyApplication.cxx b/Ivy/IvyApplication.cxx index a262fa2..4b41bbe 100644 --- a/Ivy/IvyApplication.cxx +++ b/Ivy/IvyApplication.cxx @@ -12,6 +12,9 @@ #define ARG_START 2 #define ARG_END 3 +#define MAXPORT(a,b) ((a>b) ? a : b) + + static char * firstArg( char *s, const char separator ) { char *ptr = s; @@ -46,6 +49,8 @@ IvyApplication::IvyApplication(Ivy * bus) remoteService = 0; /* unknown or unconnected application */ appname = "Unknown"; AppConnectedCallbackCalled = false; + readyToSend = 0; + InitializeCriticalSection(&m_SendReadySection ); } IvyApplication::~IvyApplication() @@ -56,6 +61,9 @@ IvyApplication::~IvyApplication() regexp_in.clear(); if ( m_hSocket != INVALID_SOCKET ) Close(); + // Release resources used by the critical section object. + DeleteCriticalSection(&m_SendReadySection); + } @@ -87,7 +95,14 @@ UINT IvyApplication::Create() #endif return port; } - +void IvyApplication::SendReadyToPeer() +{ + EnterCriticalSection (&m_SendReadySection); + readyToSend++; + if ( !bus->ready_message.empty() && readyToSend == 2 ) + SendMsg( bus->ready_message.c_str() ); + LeaveCriticalSection (&m_SendReadySection); +} void IvyApplication::OnReceive(char * line) { int err; @@ -191,7 +206,7 @@ void IvyApplication::OnReceive(char * line) } break; case StartRegexp: - + { #ifdef IVY_DEBUG TRACE("Regexp Start id=%d\n", id); #endif //IVY_DEBUG @@ -199,12 +214,29 @@ void IvyApplication::OnReceive(char * line) appname = arg; /* remote socket port */ remoteService = id; - if ( bus->CheckConnected( this ) ) + IvyApplication *other = bus->CheckConnected( this ); + if ( other ) { - TRACE("Quitting already connected %s\n", appname.c_str()); - SendMsg( Error, Error, "already connected" ); -// bus->RemoveApplication( this ); - Close(); + // Dilemma choose the rigth client to close + // the symetric processing will try to close each other + // only one side may be closed + IvyApplication *target; + if (MAXPORT(other->GetLocalPort(), other->GetRemotePort()) > MAXPORT( this->GetLocalPort(), this->GetRemotePort() )) + { + target = other; + TRACE("choose %s other ports %d,%d\n", appname.c_str(), target->GetLocalPort(), target->GetRemotePort()); + } + else + { + target = this; + TRACE("choose %s this ports %d,%d\n", appname.c_str(), target->GetRemotePort(), target->GetLocalPort()); + } + + TRACE("Quitting already connected %s\n", appname.c_str()); + target->SendMsg( Error, Error, "already connected" ); + // bus->RemoveApplication( target ); + target->Close(); + } } break; case EndRegexp: @@ -215,8 +247,7 @@ void IvyApplication::OnReceive(char * line) bus->CallApplicationConnectedCallback( this ); AppConnectedCallbackCalled = true; - if ( !bus->ready_message.empty() ) - SendMsg( bus->ready_message.c_str() ); + SendReadyToPeer(); break; case Msg: diff --git a/Ivy/IvyApplication.h b/Ivy/IvyApplication.h index 7191400..8132560 100644 --- a/Ivy/IvyApplication.h +++ b/Ivy/IvyApplication.h @@ -51,10 +51,14 @@ public: void Create( const char * host, UINT &port, const char* name ); virtual void OnAccept(int nErrorCode); virtual void OnClose(int nErrorCode); - - +protected: + void SendReadyToPeer(); + // Implementation protected: + int readyToSend; + CRITICAL_SECTION m_SendReadySection; + ivy::string appname; bool AppConnectedCallbackCalled; Ivy *bus; diff --git a/Ivy/ThreadedSocket.cxx b/Ivy/ThreadedSocket.cxx index 7d43bb5..03b062e 100644 --- a/Ivy/ThreadedSocket.cxx +++ b/Ivy/ThreadedSocket.cxx @@ -70,6 +70,28 @@ void CThreadedSocket::GetSockName(ivy::string & rSocketAddress, UINT& rSocketPor rSocketAddress = inet_ntoa(sockAddr.sin_addr); } +unsigned short int CThreadedSocket::GetLocalPort() +{ + int err; + struct sockaddr_in name; + socklen_t len = sizeof(name); + + err = getsockname (m_hSocket, (struct sockaddr *)&name, &len ); + if (err < 0 ) return 0; + return name.sin_port; +} +unsigned short int CThreadedSocket::GetRemotePort() +{ + int err; + struct sockaddr_in name; + socklen_t len = sizeof(name); + + err = getpeername (m_hSocket, (struct sockaddr *)&name, &len ); + if (err < 0 ) return 0; + return name.sin_port; +} + + ///////////////////////////////////////////////////////////////////////////// // CAscynSocket Operations diff --git a/Ivy/ThreadedSocket.h b/Ivy/ThreadedSocket.h index ad33c3e..7c22efd 100644 --- a/Ivy/ThreadedSocket.h +++ b/Ivy/ThreadedSocket.h @@ -56,6 +56,10 @@ public: size_t SendTo(const void* lpBuf, size_t nBufLen, unsigned int nHostPort, const char * lpszHostAddress = 0, int nFlags = 0); + unsigned short int GetLocalPort(); + + unsigned short int GetRemotePort(); + inline int GetPeerName(SOCKADDR* lpSockAddr, int* lpSockAddrLen) { -- cgit v1.1