[ace-users] ACE_TP_Reactor:random crash sometimes
Mihai Bucica
misu200 at yahoo.com
Tue Jun 12 08:21:30 CDT 2007
--- "Douglas C. Schmidt" <schmidt at dre.vanderbilt.edu>
wrote:
>
> Hi Mihai,
>
> That behavior shouldn't be happening in general,
> but without seeing
> your sample program it's hard to know what's going
> on. Can you post a
> very simple example that illustrates what's
> happening?
Sure. Here it is a simple example showing this
behaviour:
RequestResponse_Handler.cpp:
----------------------------------------
#include "ace_common.h"
#include "RequestResponse_Handler.h"
using namespace std;
RequestResponse_Handler::RequestResponse_Handler
(ACE_Thread_Manager *thr_mgr)
: ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_MT_SYNCH>
(thr_mgr),
notifier_ (0, this, ACE_Event_Handler::WRITE_MASK)
{
this->reactor (ACE_Reactor::instance ());
}
int RequestResponse_Handler::open (void *p) {
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT
("RequestResponse_Handler::open\n")));
if (super::open (p) == -1)
return -1;
this->notifier_.reactor (this->reactor ());
this->msg_queue ()->notification_strategy
(&this->notifier_);
}
int RequestResponse_Handler::handle_output
(ACE_HANDLE)
{
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("(%t)
RequestResponse_Handler::handle_output\n")));
ACE_Message_Block *mb;
ACE_Time_Value nowait (ACE_OS::gettimeofday ());
//here we send messages from the synchronized
ACE_Message_Queue inherited from ACE_Task
while (-1 != this->getq (mb, &nowait))
{
ssize_t send_cnt =
this->peer ().send (mb->rd_ptr (), mb->length
());
if (send_cnt == -1) {
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("ouputing error\n")));
return -1;
}
else {
mb->rd_ptr (static_cast<size_t> (send_cnt));
}
if (mb->length () > 0)
{
this->ungetq (mb);
break;
}
mb->release ();
}
if (this->msg_queue ()->is_empty ())
this->reactor ()->cancel_wakeup
(this, ACE_Event_Handler::WRITE_MASK);
else
this->reactor ()->schedule_wakeup
(this, ACE_Event_Handler::WRITE_MASK);
return 0;
}
int RequestResponse_Handler::handle_input (ACE_HANDLE
fd)
{
ACE_TCHAR buffer[BUFSIZ];
memset(buffer,0,BUFSIZ*sizeof(ACE_TCHAR));
ssize_t result = this->peer ().recv (buffer,BUFSIZ);
if (result > 0)
{
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("(%t) svr input; fd: 0x%x;
input: %s\n"),
fd,
buffer));
ACE_Message_Block *mb = new
ACE_Message_Block(sizeof(buffer)+1);
mb->copy(buffer,sizeof(buffer));
this->putq(mb);
return -1;
}
else
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("(%t)
RequestResponse_Handler: 0x%x peer closed (0x%x)\n"),
this, fd));
return -1;
}
int RequestResponse_Handler::handle_close (ACE_HANDLE
fd, ACE_Reactor_Mask)
{
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("(%t) svr close; fd: 0x%x\n"),
fd));
return super::handle_close();
}
----------------------------------
main.cpp:
----------------------------------
#include "ace_common.h"
#include "RequestResponse_Handler.h"
#include "WorkerThread.h"
static const ACE_TCHAR *rendezvous = ACE_TEXT
("127.0.0.1:10010");
int svr_thrno = 3; // number of worker threads
typedef ACE_Strategy_Acceptor<RequestResponse_Handler,
ACE_SOCK_ACCEPTOR> ACCEPTOR;
int ACE_TMAIN (int, ACE_TCHAR *[])
{
ACE_TP_Reactor sr;
ACE_Reactor new_reactor (&sr);
ACE_Reactor::instance (&new_reactor);
ACCEPTOR acceptor;
ACE_INET_Addr accept_addr (rendezvous);
if (acceptor.open (accept_addr) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("open")),
1);
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("(%t) Spawning %d server
threads...\n"),
svr_thrno));
WorkerThread worker;
worker.activate (THR_NEW_LWP | THR_JOINABLE,
svr_thrno);
ACE_Thread_Manager::instance ()->wait ();
return 0;
}
----------------------------------
WhorkerThread.h:
----------------------------------
#include "ace_common.h"
#ifndef _WORKER_THREAD
#define _WORKER_THREAD
static int reactor_event_hook (ACE_Reactor *)
{
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("(%t) handling events
....\n")));
return 0;
}
class WorkerThread : public ACE_Task_Base
{
public:
virtual int svc (void)
{
ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("(%t) Running the
event loop\n")));
int result =ACE_Reactor::instance
()->run_reactor_event_loop(&reactor_event_hook);
if (result == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("(%t) %p\n"),
ACE_TEXT ("Error handling
events")),
0);
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("(%t) Done handling
events.\n")));
return 0;
}
};
#endif
-----------------------------------
RequestResponse_Handler.h:
-----------------------------------
#ifndef __REQUEST_RESPONSE_HANDLER_H_
#define __REQUEST_RESPONSE_HANDLER_H_
#include "ace_common.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
class ACE_Thread_Manager;
ACE_END_VERSIONED_NAMESPACE_DECL
class RequestResponse_Handler : public
ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_MT_SYNCH>
{
typedef ACE_Svc_Handler<ACE_SOCK_STREAM,
ACE_MT_SYNCH> super;
public:
RequestResponse_Handler (ACE_Thread_Manager *tm =
0);
virtual int open (void *p);
virtual ~RequestResponse_Handler() {
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("(%t)
~RequestResponse_Handler()\n")));
}
protected:
virtual int handle_input (ACE_HANDLE fd =
ACE_INVALID_HANDLE);
virtual int handle_close (ACE_HANDLE fd,
ACE_Reactor_Mask = 0);
virtual int handle_output (ACE_HANDLE);
private:
ACE_Reactor_Notification_Strategy notifier_;
};
#endif
--------------------------------------------
I'm testing the program with 'telnet localhost 10010'
and I get the following output sometimes(and
crash...still sometimes):
RequestResponse_Handler::open
(2544) handling events ....
(2544) handling events ....
(2588) handling events ....
(2544) svr input; fd: 0x704; input: g
(2588) RequestResponse_Handler::handle_output
(2544) svr close; fd: 0x704
(2544) ~RequestResponse_Handler()
(2544) handling events ....
(2588) handling events ....
As you can see thread 2588 calls handle_output() on
our handle while thread 2544 is still working with
that handle:
(2544) svr input; fd: 0x704; input: g (this is
from handle_output() )
(2588) RequestResponse_Handler::handle_output
(2544) svr close; fd: 0x704 (this is from
handle_close() )
____________________________________________________________________________________
Building a website is a piece of cake. Yahoo! Small Business gives you all the tools to get online.
http://smallbusiness.yahoo.com/webhosting
More information about the Ace-users
mailing list