1

编辑:我现在已经对我的代码进行了一些编辑,以便对“所有”代码有一个粗略的了解。也许这可能有助于识别问题;)

我已经集成了以下简单的代码片段,如果从 TCP 套接字读取数据,则取消计时器,否则取消从套接字读取的数据

// file tcp.cpp
void CheckTCPSocket()
{
TRequestStatus iStatus;
TSockXfrLength len;

int timeout = 1000;
RTimer timer;
TRequestStatus timerstatus;

TPtr8 buff;
iSocket.RecvOneOrMore( buff, 0, iStatus, len );

timer.CreateLocal();

timer.After(timerstatus, timeout);
// Wait for two requests – if timer completes first, we have a
// timeout.
User::WaitForRequest(iStatus, timerstatus);

if(timerstatus.Int() != KRequestPending)
{
  iSocket.CancelRead();
}
else
{
  timer.Cancel();
}
timer.Close();
}

// file main.cpp
void TestActiveObject::RunL()
{
  TUint Data;
  MQueue.ReceiveBlocking(Data);
  CheckTCPSocket();
  SetActive();
}

这部分在活动对象中执行,由于集成了上面的代码片段,我总是得到内核恐慌:E32User-CBase 46:这个恐慌是由活动调度程序 CActiveScheduler 引发的。它是由杂散信号引起的。

在执行这段代码之前,我的代码从来没有任何问题;代码执行良好,因为从套接字读取数据然后取消并关闭计时器。我不明白计时器对象如何对 AO 产生任何影响。

如果有人能指出我正确的方向,那就太好了。

谢谢

4

3 回答 3

1

这可能是另一个活动对象完成(不是这两个之一)或未调用 SetActive() 的问题。请参阅诺基亚论坛。很难说没有看到你所有的代码!

BTW User::WaitForRequest() 几乎总是一个坏主意。看看为什么在这里

于 2009-09-24T09:25:45.213 回答
0

切勿混合活动对象和User::WaitForRequest().

(嗯,几乎从来没有。当你确切地知道你在做什么时,它可能没问题,但你发布的代码表明你仍然需要学习。)

当线程请求信号量RThread::RequestComplete()由异步服务提供者发出信号时,您会收到杂散信号恐慌,并且正在等待信号量的活动调度程序User::WaitForAnyRequest()尝试查找已完成的活动对象,以便RunL()可以调用它,但找不到任何在其活动对象列表中。

在这种情况下,您有两个正在进行的请求,这两个请求都不受活动调度程序的控制(例如,不使用CActive::iStatusas TRequestStatus;在不涉及异步请求SetActive()的对象上CActive::iStatus发出是代码中的另一个错误,但不是原因杂散信号)。您等待其中一个完成,WaitForRequest()但根本不等待另一个完成。另一个请求的完成信号将转到活动调度程序的WaitForAnyRequest(),从而产生杂散信号。如果你取消一个请求,你仍然需要等待线程请求信号量。

最好的解决方案是将超时计时器也设为活动对象。看看CTimer课堂。

WaitForRequest另一种解决方案是在尚未完成的请求上添加另一个。

于 2009-09-24T11:26:33.863 回答
0

您正在调用TestActiveObject::SetActive(),但没有调用任何设置TestActiveObject::iStatus为 的方法KRequestPending。这将造成杂散信号恐慌。

代码中的唯一iStatus变量是该CheckTCPSocket()方法的本地变量。

于 2009-09-28T19:25:10.483 回答