WaitForRequest 超时崩溃
编辑:我现在已经稍微编辑了我的代码,以便对“所有”代码有一个粗略的了解。也许这个 可能有助于识别问题;)
我集成了以下简单的代码片段,如果数据存在,则取消计时器 从 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这可能是另一个活动对象完成(不是这两个之一)或未调用 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.
切勿混合活动对象和
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 withUser::WaitForAnyRequest()
tries to look for an active object that was completed so that itsRunL()
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 theTRequestStatus
; issuingSetActive()
on an object whereCActive::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 withWaitForRequest()
but don't wait for the other to complete at all. The other request's completion signal will go to the active scheduler'sWaitForAnyRequest()
, 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.您正在调用
TestActiveObject::SetActive()
,但没有调用任何将TestActiveObject::iStatus
设置为KRequestPending
的方法。这将造成杂散信号恐慌。代码中唯一的
iStatus
变量是CheckTCPSocket()
方法的本地变量。You are calling
TestActiveObject::SetActive()
but there is no call to any method that setsTestActiveObject::iStatus
toKRequestPending
. This will create the stray signal panic.The only
iStatus
variable in your code is local to theCheckTCPSocket()
method.