[ace-users] HP-UX Itanium: TCP/IP connections stay in CLOSE_WAIT state.

John Jenniskens john.jenniskens at HumanInference.com
Thu Jun 14 09:31:07 CDT 2007


ACE VERSION 5.4 and 5.5
 
HOST MACHINE and OPERATING SYSTEM
 HP  HP-UX 11.23 on Itanium Platform  (HP-UX  B.11.23 U ia64)
 
Compiler GCC 4.0.2 (With patches suplied by HP for wstring support)
 
$ACE_ROOT/ace/config.h:
#ifndef ACE_CONFIG_H
// ACE_CONFIG_H is defined in the included header
 
#undef ACE_BUILD_DLL
#ifndef ACE_AS_STATIC_LIBS
#define ACE_AS_STATIC_LIBS
#endif
 
#ifndef HPUX_VERS
#define HPUX_VERS 1123
#endif
 
#ifndef ACE_HAS_THREADS
#define ACE_HAS_THREADS 1
#endif
 
#ifndef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 199506L
#endif
 
#ifndef ACE_HAS_EXCEPTIONS
#define ACE_HAS_EXCEPTIONS
#endif
 
#ifndef __ACE_INLINE__
#define __ACE_INLINE__
#endif
 
#include <ace/config-hpux-11.00.h>
 
#endif  // ACE_CONFIG_H
 

$ACE_ROOT/include/makeinclude/platform_macros.GNU:
static_libs_only = 1
CPPFLAGS += -fPIC
include $(ACE_ROOT)/include/makeinclude/platform_hpux_gcc.GNU
 
THE PROBLEM AFFECTS: EXECUTION
 
    SYNOPSIS:
TCP/IP connections stay in CLOSE_WAIT state.
 
    DESCRIPTION:
We implemented a server using the ACE_Svc_Handler<ACE_SOCK_STREAM,
ACE_NULL_SYNCH>. The implementation works fine on different platforms,
but on itanium, connections closed by the client stay in the CLOSE_WAIT
state (netstat). Every closed connection adds a new CLOSE_WAIT.
Resources are limited, so after some time we are forced to restart the
server.
 
Our analysis:
 
  Normal behaviour:
 
  Svc_Handler.cpp
  ::operator new gets a dynamic_instance by calling
ACE_Dynamic::instance()
  and calls set() upon the dynamic_instance and thereby setting its
value to 1
 
  The ACE_Svc_Handler constructor assigns the value
  ACE_Dynamic::instance ()->is_dynamic () to the dynamic_ data member of
this
  ACE_Svc_Handler.
 
  The ACE_Svc_Handler::destroy() method checks the
ACE_Svc_Handler::dynamic_
  data member and deletes this ACE_Svc_Handler in case it has value 1
 

  But in case of the itanium:
 
  The call ACE_Dynamic::instance() in the ACE_Svc_Handler constructor
creates
  a new instance in stead of using the instance initialized in the
  ::operator new. So, the dynamic_
  member gets a value 0. And this prevents the destroy method calling
delete.
  And now the TCP/IP handle is not closed, resulting in a CLOSE_WAIT.
 
  It looks like the ACE_Dynamic::instance implemented with a
ACE_TSS_Singleton
  does not work correctly.
 

    REPEAT BY:
I added print statements printing the address of the dynamic instance in
ace/Dynamic.i and ace/Svc_Handler.cpp. This
shows the problem in the ace/tests/Svc_Handler_Test.cpp for ACE 5.4
 
Index: Dynamic.i
===================================================================
--- Dynamic.i   (revision 19207)
+++ Dynamic.i   (working copy)
@@ -3,10 +3,13 @@
 
 // Dynamic.i
 
+#include <iostream>
+
 ACE_INLINE
 ACE_Dynamic::~ACE_Dynamic (void)
 {
   // ACE_TRACE ("ACE_Dynamic::~ACE_Dynamic");
+  std::cout << this << " ACE_Dynamic::~ACE_Dynamic" << std::endl;
 }
 
 ACE_INLINE void
@@ -14,12 +17,14 @@
 {
   // ACE_TRACE ("ACE_Dynamic::set");
   this->is_dynamic_ = 1;
+  std::cout << this << " ACE_Dynamic::set" << std::endl;
 }
 
 ACE_INLINE int
 ACE_Dynamic::is_dynamic ()
 {
   // ACE_TRACE ("ACE_Dynamic::is_dynamic");
+  std::cout << this << " ACE_Dynamic::is_dynamic " << this->is_dynamic_
<< std::endl;
   return this->is_dynamic_;
 }
 
@@ -28,4 +33,5 @@
 {
   // ACE_TRACE ("ACE_Dynamic::reset");
   this->is_dynamic_ = 0;
+  std::cout << this << " ACE_Dynamic::reset" << std::endl;
 }
 
 
 

Index: Svc_Handler.cpp
===================================================================
--- Svc_Handler.cpp     (revision 19207)
+++ Svc_Handler.cpp     (working copy)
@@ -15,6 +15,8 @@
 
 #include "ace/Dynamic.h"
 
+#include "iostream"
+
 ACE_RCSID(ace, Svc_Handler, "Svc_Handler.cpp,v 4.69 2004/01/05 22:57:06
shuston Exp")
 
 #define PR_ST_1 ACE_PEER_STREAM_1
@@ -44,6 +46,7 @@
   ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::operator new");
 
   ACE_Dynamic *const dynamic_instance = ACE_Dynamic::instance ();
+  std::cout << "new: dynamic_instance = "<< dynamic_instance <<
std::endl;
 
   if (dynamic_instance == 0)
     {
@@ -72,6 +75,7 @@
   ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::operator
new(nothrow)");
 
   ACE_Dynamic *const dynamic_instance = ACE_Dynamic::instance ();
+  std::cout << "new2: dynamic_instance = "<< dynamic_instance <<
std::endl;
 
   if (dynamic_instance == 0)
     {
@@ -100,12 +104,15 @@
 
   // Only delete ourselves if we're not owned by a module and have
   // been allocated dynamically.
+  std::cout << "destroy: dynamic_ = " << this->dynamic_ << std::endl;
   if (this->mod_ == 0 && this->dynamic_ && this->closing_ == 0)
+  {
     // Will call the destructor, which automatically calls <shutdown>.
     // Note that if we are *not* allocated dynamically then the
     // destructor will call <shutdown> automatically when it gets run
     // during cleanup.
     delete this;
+  }
 }
 
 template <PR_ST_1, ACE_SYNCH_DECL> void
@@ -142,10 +149,13 @@
   // work correctly in multi-threaded programs by using our ACE_TSS
   // class.
   this->dynamic_ = ACE_Dynamic::instance ()->is_dynamic ();
+  std::cout << "construct: dynamic_ = " << this->dynamic_ << std::endl;
 
   if (this->dynamic_ != 0)
+  {
     // Make sure to reset the flag.
     ACE_Dynamic::instance ()->reset ();
+  }
 }
 
 // Default behavior for a ACE_Svc_Handler object is to be registered
 
 
Kind regards,
 
John Jenniskens 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://list.isis.vanderbilt.edu/pipermail/ace-users/attachments/20070614/00d01540/attachment.htm


More information about the Ace-users mailing list