找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 6000|回复: 3

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

[复制链接]
发表于 2009-3-31 09:57:34 | 显示全部楼层 |阅读模式
下面是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 编辑 ]
 楼主| 发表于 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 编辑 ]
 楼主| 发表于 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句柄的,
但是为什么没有按照预想的调用,还是别的地方调用了,我没有发现呢?
 楼主| 发表于 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 编辑 ]
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-12-22 16:37 , Processed in 0.014374 second(s), 6 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表