modern 发表于 2009-3-31 09:57:34

请教高手,关于jaws2的几个没看懂的地方

下面是jaws2的DLL的源代码。
JAWS_Server::open (JAWS_Pipeline_Handler *protocol,
                   JAWS_Dispatch_Policy *policy)
{
if (policy == 0)
    policy = &this->policy_;
JAWS_Data_Block *db = new JAWS_Data_Block;
if (db == 0)
    {
      ACE_DEBUG ((LM_DEBUG,
                  "(%t) JAWS_Server::open, could not create Data_Block\n"));
      return -1;
    }
// initialize data block
db->task (JAWS_Pipeline_Accept_Task_Singleton::instance ());
db->policy (policy);
db->io_handler (0);
db->task ()->next (protocol);
// prime the acceptor if appropriate
if (this->dispatch_ == 1)
    {
#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) || defined (ACE_HAS_AIO_CALLS)
    int n = this->nthreads_;
      if (this->concurrency_ == 1)
      n = 1;
      for (int i = 0; i < n * this->ratio_ - n; i++)
      db->task ()->put (db);
#endif /* ACE_HAS_WIN32_OVERLAPPED_IO || ACE_HAS_AIO_CALLS */
    }
// The message block should contain an INET_Addr, and call the
// io->accept (INET_Addr) method!
policy->concurrency ()->put (db);
ACE_Thread_Manager::instance ()->wait ();
db->release ();
return 0;
}
下面是main函数的源代码
static JAWS_HTTP_10_Read_Task HTTP_Read;
static JAWS_HTTP_10_Parse_Task HTTP_Parse;
static JAWS_HTTP_10_Write_Task HTTP_Write;

JAWS_Server server (argc, argv);
HTTP_Read.next (&HTTP_Parse);
HTTP_Parse.next (&HTTP_Write);
// HTTP_Write.next (JAWS_Pipeline_Done_Task_Singleton::instance ());
if (server.open (&HTTP_Read) == -1)
    ACE_DEBUG ((LM_DEBUG, "JAWS: Error openning server\n"));

JAWS_HTTP_10_***_Task都是继承自JAWS_Pipeline_Handler的。
我有以下几个问题。
1.看到main函数中,server.open 调用之前,使用ACE_Task的next方法把多个JAWS_Pipeline_Handler的派生类,连接到一起。
参考了一些资料,大概可以理解,HTTP_Read.next (&HTTP_Parse);HTTP_Parse.next (&HTTP_Write);
是将我们自定义的处理流程串行保存起来,然后在jaws内部,依次做处理,比如读报文,解析,然后写回去。
内部使用db->task ()->next (protocol);设置进去,然后 db->task ()->put (db);把其设置到JAWS_IO_Handler内部,内部的注释说:
“当io请求完成之后,使用这个task的句柄”。
然后我就没有找到被设置的task如何被JAWS_IO_Handler以及其派生类使用,连接过来之后,
如何开始调用第一个JAWS_HTTP_10_Read_Task HTTP_Read(AWS_Pipeline_Handler的派生类)呢?

[ 本帖最后由 modern 于 2009-3-31 11:00 编辑 ]

modern 发表于 2009-3-31 10:08:42

http://www.acejoy.com/bbs/viewthread.php?tid=830&extra=page%3D1
参考了版主的文章,发现很多观点是一致的:其中第4,5,6步,我想我第一个问题应该是与这个有关系。
5. 使用JAWS_Data_Block::payload()来与pipeline的下一个任务通信
   (pipleline就是处理协议栈的Stream框架的实例)
至于是如何通信的正是我关心的内容,希望版主能指点一下。

[ 本帖最后由 modern 于 2009-3-31 10:40 编辑 ]

modern 发表于 2009-3-31 11:58:30

继续分析代码,参考下面,以异步请求为例,ACE_Service_Handler的Handle_Read_Stream方法,
会调用到read_complete,完成客户端过来读操作。
void
JAWS_IO_Handler::read_complete (ACE_Message_Block *data)
{
ACE_UNUSED_ARG (data);
// We can call back into the pipeline task at this point
// this->pipeline_->read_complete (data);
this->status_ |= READ_OK;
this->status_ &= (READ_OK+1);
}

按道理来说,这里应该回调task的put方法,将data放进去,
然后即可以开始我们配置的pipeline的处理流程。
看代码注释的说明,貌似也是这个意思。
观察被注释掉的代码,应该确认我理解的没错,至少以前她是这么做的。
这里JAWS_IO_Handler是持有pipeline的task句柄的,
但是为什么没有按照预想的调用,还是别的地方调用了,我没有发现呢?

modern 发表于 2009-3-31 16:00:09

仔细观察JAWS_Message_Block,这个对象会贯穿整个tcp请求的始终,
接口使用者把自己实现的JAWS_Pipeline_Handler的派生类串接起来,
存放到JAWS_Message_Block的成员变量中,根据定制的并发策略(pool,threadperrequest),
保证JAWS_Message_Block始终被一个线程处理,通过JAWS_Data_Block::payload()在pipeline之间传递数据。
然后在一个连接到来的时候,预先定义的JAWS_Pipeline_Accept_Task会最先被调用,
然后依次调用自己实现的串接好的JAWS_Pipeline_Handler的派生类,
直至完成,最后调用预先定义的JAWS_Pipeline_Done_Task,清理TCP连接资源。
问题解决。

[ 本帖最后由 modern 于 2009-3-31 16:40 编辑 ]
页: [1]
查看完整版本: 请教高手,关于jaws2的几个没看懂的地方