WaitForRequest 超时崩溃

发布于 2024-08-05 11:48:23 字数 1012 浏览 2 评论 0原文

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

我集成了以下简单的代码片段,如果数据存在,则取消计时器 从 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 有何影响。

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

谢谢

EDIT: I have now edited my code a bit to have a rough idea of "all" the code. Maybe this
might be helpful to identify the problem ;)

I have integrated the following simple code fragement which either cancels the timer if data
is read from the TCP socket or otherwise it cancels the data read from the socket

// 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();
}

This part is executed within active Object and since integrating the code piece above I always get the kernel panic:
E32User-CBase 46: This panic is raised by an active scheduler, a CActiveScheduler. It is caused by a stray signal.

I never had any problem with my code until now this piece of code is executed; code executes fine as data is read from the socket and
then the timer is canceled and closed. I do not understand how the timer object has here any influence on the AO.

Would be great if someone could point me to the right direction.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

稚气少女 2024-08-12 11:48:23

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

顺便说一句,User::WaitForRequest() 几乎总是是一个坏主意。请参阅为什么在这里

This could be a problem with another active object completing (not one of these two), or SetActive() not being called. See Forum Nokia. Hard to say without seeing all your code!

BTW User::WaitForRequest() is nearly always a bad idea. See why here.

南巷近海 2024-08-12 11:48:23

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

(好吧,几乎从来没有。当您确切地知道自己在做什么时就可以了,但是您发布的代码表明您仍然需要学习一些东西。)

当线程请求信号量用 RThread::RequestComplete() 由异步服务提供者和使用 User::WaitForAnyRequest() 等待信号量的活动调度程序尝试查找已完成的活动对象以便可以调用其 RunL() ,但在其活动对象列表中找不到任何对象。

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

最好的解决方案是使超时计时器也成为活动对象。看一下CTimer 类。

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

Never mix active objects and User::WaitForRequest().

(Well, almost never. When you know exactly what you are doing it can be ok, but the code you posted suggests you still have some learning to do.)

You get the stray signal panic when the thread request semaphore is signalled with RThread::RequestComplete() by the asynchronous service provider and the active scheduler that was waiting on the semaphore with User::WaitForAnyRequest() tries to look for an active object that was completed so that its RunL() could be called, but cannot find any in its list of active objects.

In this case you have two ongoing requests, neither of which is controlled by the active scheduler (for example, not using CActive::iStatus as the TRequestStatus; issuing SetActive() on an object where CActive::iStatus is not involved in an async request is another error in your code but not the reason for stray signal). You wait for either one of them to complete with WaitForRequest() but don't wait for the other to complete at all. The other request's completion signal will go to the active scheduler's WaitForAnyRequest(), resulting in stray signal. If you cancel a request, you will still need to wait on the thread request semaphore.

The best solution is to make the timeout timer an active object as well. Have a look at the CTimer class.

Another solution is just to add another WaitForRequest on the request not yet completed.

我不是你的备胎 2024-08-12 11:48:23

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

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

You are calling TestActiveObject::SetActive() but there is no call to any method that sets TestActiveObject::iStatus to KRequestPending. This will create the stray signal panic.

The only iStatus variable in your code is local to the CheckTCPSocket() method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文