<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=us-ascii">
<META content="MSHTML 6.00.6000.16481" name=GENERATOR></HEAD>
<BODY><FONT face=Tahoma size=2>
<DIV><BR>ACE VERSION 5.4 and 5.5<BR> <BR>HOST MACHINE and OPERATING
SYSTEM<BR> HP HP-UX 11.23 on Itanium Platform (HP-UX
B.11.23 U ia64)<BR> <BR>Compiler GCC 4.0.2 (With patches suplied by HP for
wstring support)<BR> <BR>$ACE_ROOT/ace/config.h:<BR>#ifndef
ACE_CONFIG_H<BR>// ACE_CONFIG_H is defined in the included header</DIV>
<DIV> </DIV>
<DIV>#undef ACE_BUILD_DLL<BR>#ifndef ACE_AS_STATIC_LIBS<BR>#define
ACE_AS_STATIC_LIBS<BR>#endif</DIV>
<DIV> </DIV>
<DIV>#ifndef HPUX_VERS<BR>#define HPUX_VERS 1123<BR>#endif</DIV>
<DIV> </DIV>
<DIV>#ifndef ACE_HAS_THREADS<BR>#define ACE_HAS_THREADS 1<BR>#endif</DIV>
<DIV> </DIV>
<DIV>#ifndef _POSIX_C_SOURCE<BR>#define _POSIX_C_SOURCE 199506L<BR>#endif</DIV>
<DIV> </DIV>
<DIV>#ifndef ACE_HAS_EXCEPTIONS<BR>#define ACE_HAS_EXCEPTIONS<BR>#endif</DIV>
<DIV> </DIV>
<DIV>#ifndef __ACE_INLINE__<BR>#define __ACE_INLINE__<BR>#endif</DIV>
<DIV> </DIV>
<DIV>#include <ace/config-hpux-11.00.h></DIV>
<DIV> </DIV>
<DIV>#endif // ACE_CONFIG_H</DIV>
<DIV> </DIV>
<DIV><BR>$ACE_ROOT/include/makeinclude/platform_macros.GNU:<BR>static_libs_only
= 1<BR>CPPFLAGS += -fPIC<BR>include
$(ACE_ROOT)/include/makeinclude/platform_hpux_gcc.GNU</DIV>
<DIV> </DIV>
<DIV>THE PROBLEM AFFECTS: EXECUTION</DIV>
<DIV> </DIV>
<DIV> SYNOPSIS:<BR>TCP/IP connections stay in CLOSE_WAIT
state.</DIV>
<DIV> </DIV>
<DIV> DESCRIPTION:<BR>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.</DIV>
<DIV> </DIV>
<DIV>Our analysis:</DIV>
<DIV> </DIV>
<DIV> Normal behaviour:</DIV>
<DIV> </DIV>
<DIV> Svc_Handler.cpp<BR> ::operator new gets a dynamic_instance by
calling ACE_Dynamic::instance()<BR> and calls set() upon the
dynamic_instance and thereby setting its value to 1</DIV>
<DIV> </DIV>
<DIV> The ACE_Svc_Handler constructor assigns the value<BR>
ACE_Dynamic::instance ()->is_dynamic () to the dynamic_ data member of
this<BR> ACE_Svc_Handler.</DIV>
<DIV> </DIV>
<DIV> The ACE_Svc_Handler::destroy() method checks the
ACE_Svc_Handler::dynamic_<BR> data member and deletes this ACE_Svc_Handler
in case it has value 1</DIV>
<DIV> </DIV>
<DIV><BR> But in case of the itanium:</DIV>
<DIV> </DIV>
<DIV> The call ACE_Dynamic::instance() in the ACE_Svc_Handler constructor
creates<BR> a new instance in stead of using the instance initialized in
the<BR> ::operator new. So, the dynamic_<BR> member gets a value 0.
And this prevents the destroy method calling delete.<BR> And now the
TCP/IP handle is not closed, resulting in a CLOSE_WAIT.</DIV>
<DIV> </DIV>
<DIV> It looks like the ACE_Dynamic::instance implemented with a
ACE_TSS_Singleton<BR> does not work correctly.</DIV>
<DIV> </DIV>
<DIV><BR> REPEAT BY:<BR>I added print statements printing the
address of the dynamic instance in ace/Dynamic.i and ace/Svc_Handler.cpp.
This<BR>shows the problem in the ace/tests/Svc_Handler_Test.cpp for ACE
5.4</DIV>
<DIV> </DIV>
<DIV>Index:
Dynamic.i<BR>===================================================================<BR>---
Dynamic.i (revision 19207)<BR>+++ Dynamic.i (working
copy)<BR>@@ -3,10 +3,13 @@</DIV>
<DIV> </DIV>
<DIV> // Dynamic.i</DIV>
<DIV> </DIV>
<DIV>+#include
<iostream><BR>+<BR> ACE_INLINE<BR> ACE_Dynamic::~ACE_Dynamic
(void)<BR> {<BR> // ACE_TRACE
("ACE_Dynamic::~ACE_Dynamic");<BR>+ std::cout << this << "
ACE_Dynamic::~ACE_Dynamic" << std::endl;<BR> }</DIV>
<DIV> </DIV>
<DIV> ACE_INLINE void<BR>@@ -14,12 +17,14 @@<BR> {<BR> //
ACE_TRACE ("ACE_Dynamic::set");<BR> this->is_dynamic_ =
1;<BR>+ std::cout << this << " ACE_Dynamic::set" <<
std::endl;<BR> }</DIV>
<DIV> </DIV>
<DIV> ACE_INLINE int<BR> ACE_Dynamic::is_dynamic
()<BR> {<BR> // ACE_TRACE
("ACE_Dynamic::is_dynamic");<BR>+ std::cout << this << "
ACE_Dynamic::is_dynamic " << this->is_dynamic_ <<
std::endl;<BR> return this->is_dynamic_;<BR> }</DIV>
<DIV> </DIV>
<DIV>@@ -28,4 +33,5 @@<BR> {<BR> // ACE_TRACE
("ACE_Dynamic::reset");<BR> this->is_dynamic_ = 0;<BR>+
std::cout << this << " ACE_Dynamic::reset" <<
std::endl;<BR> }</DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV><BR>Index:
Svc_Handler.cpp<BR>===================================================================<BR>---
Svc_Handler.cpp (revision 19207)<BR>+++
Svc_Handler.cpp (working copy)<BR>@@ -15,6 +15,8
@@</DIV>
<DIV> </DIV>
<DIV> #include "ace/Dynamic.h"</DIV>
<DIV> </DIV>
<DIV>+#include "iostream"<BR>+<BR> ACE_RCSID(ace, Svc_Handler,
"Svc_Handler.cpp,v 4.69 2004/01/05 22:57:06 shuston Exp")</DIV>
<DIV> </DIV>
<DIV> #define PR_ST_1 ACE_PEER_STREAM_1<BR>@@ -44,6 +46,7
@@<BR> ACE_TRACE ("ACE_Svc_Handler<PR_ST_2,
ACE_SYNCH_USE>::operator new");</DIV>
<DIV> </DIV>
<DIV> ACE_Dynamic *const dynamic_instance = ACE_Dynamic::instance
();<BR>+ std::cout << "new: dynamic_instance = "<<
dynamic_instance << std::endl;</DIV>
<DIV> </DIV>
<DIV> if (dynamic_instance == 0)<BR> {<BR>@@
-72,6 +75,7 @@<BR> ACE_TRACE ("ACE_Svc_Handler<PR_ST_2,
ACE_SYNCH_USE>::operator new(nothrow)");</DIV>
<DIV> </DIV>
<DIV> ACE_Dynamic *const dynamic_instance = ACE_Dynamic::instance
();<BR>+ std::cout << "new2: dynamic_instance = "<<
dynamic_instance << std::endl;</DIV>
<DIV> </DIV>
<DIV> if (dynamic_instance == 0)<BR> {<BR>@@
-100,12 +104,15 @@</DIV>
<DIV> </DIV>
<DIV> // Only delete ourselves if we're not owned by a module and
have<BR> // been allocated dynamically.<BR>+ std::cout
<< "destroy: dynamic_ = " << this->dynamic_ <<
std::endl;<BR> if (this->mod_ == 0 && this->dynamic_
&& this->closing_ == 0)<BR>+ {<BR> //
Will call the destructor, which automatically calls
<shutdown>.<BR> // Note that if we are *not*
allocated dynamically then the<BR> // destructor will
call <shutdown> automatically when it gets run<BR>
// during cleanup.<BR> delete this;<BR>+
}<BR> }</DIV>
<DIV> </DIV>
<DIV> template <PR_ST_1, ACE_SYNCH_DECL> void<BR>@@ -142,10 +149,13
@@<BR> // work correctly in multi-threaded programs by using our
ACE_TSS<BR> // class.<BR> this->dynamic_ =
ACE_Dynamic::instance ()->is_dynamic ();<BR>+ std::cout <<
"construct: dynamic_ = " << this->dynamic_ << std::endl;</DIV>
<DIV> </DIV>
<DIV> if (this->dynamic_ != 0)<BR>+
{<BR> // Make sure to reset the
flag.<BR> ACE_Dynamic::instance ()->reset
();<BR>+ }<BR> }</DIV>
<DIV> </DIV>
<DIV> // Default behavior for a ACE_Svc_Handler object is to be
registered</DIV>
<DIV> </DIV>
<DIV></FONT> </DIV>
<DIV><FONT face=Tahoma size=2><SPAN class=450535308-14062007>Kind
regards,</SPAN></FONT></DIV>
<DIV><FONT face=Tahoma size=2></FONT> </DIV><FONT face=Georgia size=2>
<DIV><FONT face=Georgia></FONT></DIV>
<DIV><FONT face=Tahoma>John Jenniskens </FONT></DIV></FONT></BODY></HTML>