-
Notifications
You must be signed in to change notification settings - Fork 387
Description
Version
ACE+TAO+CIAO-6.2.4
Host machine and operating system
Intel(R) Core(TM) i5-10400 CPU @ 2.90GHz 2.90 GHz
Windows 10 Home 22H2
Target machine and operating system (if different from host)
Consistent with the host (both development and operation are conducted on the same machine)
Compiler name and version (including patch level)
VS Studio 2012 & SP4
The $ACE_ROOT/ace/config.h file
config-win32.h
The $ACE_ROOT/include/makeinclude/platform_macros.GNU file
Has not been modified
Contents of $ACE_ROOT/bin/MakeProjectCreator/config/default.features
None
AREA/CLASS/EXAMPLE AFFECTED:
#include "stdafx.h"
#include "ace/Reactor.h"
#include "ace/TP_Reactor.h"
#include "ace/Event_Handler.h"
#include "ace/Thread_Manager.h"
#include "ace/Handle_Set.h"
#include "ace/Init_ACE.h"
#include "ace/Log_Msg.h"
#include <ace/Event_Handler.h>
#include <ace/SOCK_Acceptor.h>
#include <iostream>
class AcceptHandler : public ACE_Event_Handler {
private:
ACE_Reactor *m_pReactor;
ACE_SOCK_Acceptor m_acceptor;
public:
AcceptHandler(ACE_Reactor *reactor = 0):
ACE_Event_Handler(),
m_pReactor(reactor == 0 ? ACE_Reactor::instance() : reactor),
m_acceptor() {
ACE_TRACE("AcceptHandler:: AcceptHandler(ACE_Reactor *)");
};
virtual ~AcceptHandler(){};
int open(int port){
ACE_INET_Addr addr(port);
if (m_acceptor.open(addr, 1) == -1)
ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("%N:%l: Failed to open ")
ACE_TEXT ("listening socket. (errno = %i: %m)\n"), errno), -1);
ACE_DEBUG((LM_DEBUG, ACE_TEXT("start server at the port %d\n"),port));
// register the handler with the reactor
if (m_pReactor->register_handler(this,
ACE_Event_Handler::ACCEPT_MASK) == -1) {
ACE_ERROR((LM_ERROR, ACE_TEXT("%N:%l: Failed to register accept ")
ACE_TEXT ("handler. (errno = %i: %m)\n"), errno));
// don't leave the acceptor open
if (m_acceptor.close() == -1)
ACE_ERROR((LM_ERROR, ACE_TEXT("%N:%l: Failed to close the socket ")
ACE_TEXT ("after previous error. (errno = %i: %m)\n"),
errno));
return -1;
}
return 0;
}
virtual ACE_HANDLE get_handle(void) const
{
return m_acceptor.get_handle();
}
virtual int handle_input(ACE_HANDLE = ACE_INVALID_HANDLE)
{
ACE_INET_Addr clientAddr;
ACE_SOCK_Stream stream;
if (m_acceptor.accept(stream, &clientAddr) == -1)
ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("%N:%l: Failed to accept ")
ACE_TEXT ("client connection. (errno = %i: %m)\n"), errno), -1);
stream.close();
return 0;
}
virtual int handle_close(ACE_HANDLE, ACE_Reactor_Mask)
{
if (m_acceptor.close() == -1) {
ACE_ERROR((LM_ERROR, ACE_TEXT("%N:%l: Failed to close the ")
ACE_TEXT ("socket. (errno = %i: %m)\n"), errno));
}
delete this;
return 0;
}
};
ACE_THR_FUNC_RETURN threadFunc(void *arg) {
ACE_Reactor *reactor = (ACE_Reactor *) arg;
reactor->owner(ACE_OS::thr_self());
reactor->run_reactor_event_loop();
return 0;
}
int main(int argc, char* argv[])
{
ACE::init();
ACE_TP_Reactor tpReactor;
ACE_Reactor reactor(&tpReactor);
AcceptHandler *pAcceptHandler = 0;
ACE_NEW_NORETURN (pAcceptHandler, AcceptHandler(&reactor));
int port = -1;
if (argc > 1)
{
port = atoi(argv[1]);
}
if (port <= 0)
port = 9955;
if (pAcceptHandler->open(port) == -1) {
delete pAcceptHandler;
ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("%N:%l: Failed to open accept ")
ACE_TEXT ("handler. Exiting.\n")), -1);
}
ACE_Thread_Manager::instance()->spawn_n(500, threadFunc, &reactor);
ACE_Thread_Manager::instance()->wait();
ACE::fini();
return 0;
}
The problem effects:
Synopsis
Handle growth
Description
After the program is run, test it using curl 127.0.0.1:9955. Each time a connection is made, it is observed in Resource Monitor that the number of handles increases by 4. We want to know the cause of this handle growth: is it due to incorrect usage? And how should we modify the program to fix it?
In the production environment, since the business logic is processed in the handle_input method of ACE_Event_Handler (and data is returned after processing is completed), and there are a large number of concurrent connections, 500 threads are initiated here. The number of these threads cannot be reduced.
Repeat by
- Run the program
- curl 127.0.0.1:9955
- It is observed in Resource Monitor that the number of handles increases by 4.