Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/411.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/css/41.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
XPCOM C++;多线程和javascript回调 背景_Javascript_C++_Multithreading_Xul_Xpcom - Fatal编程技术网

XPCOM C++;多线程和javascript回调 背景

XPCOM C++;多线程和javascript回调 背景,javascript,c++,multithreading,xul,xpcom,Javascript,C++,Multithreading,Xul,Xpcom,在XULRunner版本Belowe12.0中,它可以工作,但当我尝试将它移植到12.0或更高版本时,它会使应用程序崩溃。 主要原因是,在sdk v12或更新版本中,开发人员将代理对象删除到xpcom组件,并建议替换它 通过使用nsRunnable/nsIRunnable包装对象,并通过函数NS\u DispatchToMainThread将调用路由到主线程(单击) nsDBService::Query //main thread ok NS_DispatchToMainThread //mai

在XULRunner版本Belowe12.0中,它可以工作,但当我尝试将它移植到12.0或更高版本时,它会使应用程序崩溃。 主要原因是,在sdk v12或更新版本中,开发人员将代理对象删除到xpcom组件,并建议替换它 通过使用nsRunnable/nsIRunnable包装对象,并通过函数NS\u DispatchToMainThread将调用路由到主线程(单击)

nsDBService::Query //main thread ok
NS_DispatchToMainThread //main thread
nsResultCallback::Run //main thread
nsIDBCallback::OnInfo //main thread ok
我在开发什么? 我创建了db连接器,它是异步的,通过回调与主线程通信。 使用:xulrunnerv6,移植到xulrunnerv17或更高版本

nsDBService::Query //main thread ok
NS_DispatchToMainThread //main thread
nsResultCallback::Run //main thread
nsIDBCallback::OnInfo //main thread ok

//nsIDBCallback.idl
[可编写脚本、函数、uuid(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)]
接口nsIDBCallback:nsidbSupports{
void onInfo(在长阶段、长状态、字符串信息中);
}

//h,它是XPCOM组件
nsDBService类:公共NSIBSERVICE,nsIRunnable
{
公众:
NS_DECL_ISUPPORTS
不可执行
NS_DECL_NSIDBSERVICE
私人:
向量线程;
std::向量回调;
std::向量sqls;
nsIThread*makenethread();
无效运行IfNotBussy();
公众:
NS_IMETHODIMP查询(const char*sql,nsIDBCallback*callback);
}

//nsDBService.cpp
//将查询和其他数据添加到缓冲区,
//它是线程安全的,有使用互斥的
NS_IMETHODIMP nsDBService::Query(const char*sql,nsIDBCallback*callback)
{
回调。推回(回调);
sqls.push_-back(sql);
threads.push_back(makeNewThread());
//如果db驱动程序空闲,则运行添加的操作,
//若驱动程序是bussy,那个么调用就在缓冲区中,需要等待
runOperationIfNotBussy();
返回NS_OK;
}
void nsDBService::runOperationIfNotBussy()
{
//一些条件、测试等。
//在列表上运行第一个操作
//运行线程,仍然可以吗
if(…)threads.front()->Dispatch(这是nsIEventTarget::Dispatch_NORMAL);
}
//如果此方法被另一个线程+db查询使用,
//然后其他操作无法运行,需要等待
//像fifo一样存储和支持操作
NS_IMETHODIMP nsDBService::运行(无效)
{
//其他一些行动
//后台的真实数据库操作
int32\u t相位=3;//结束相位
int32\u t code=0;//确定
const char*msg=“确定”;
nsIDBCallback*callback=callbacks.pop();
//使用可运行接口包装回调函数
nsIRunnable*runCallback=新的nsResultCallback(回调,
阶段,
代码,
味精);
//将事件路由到主线程
NS_DispatchToMainThread(runCallback,NS_DISPATCH_NORMAL);
runOperationIfNotBussy();
}

//nsResultCallback.h
类nsResultCallback:public nsRunnable
{ 
公众:
NS_DECL_ISUPPORTS
公众:
不可执行
私人:
nsIDBCallback*回调;
int32_t再相位;
int32_t resStatus;
const char*resMessage;
公众:
nsResultCallback(nsIDBCallback*回调,
int32_t阶段,
国际地位,
const std::字符串和消息)
:回调(回调),
再相位(相位),
雷斯塔图斯(地位),
resMessage(c_str_clone(message.c_str()){};
~nsResultCallback();
};

//nsResultCallback.cpp
NS_i方法DIMP nsResultCallback::运行(无效)
{
nsresult rv=NS\u错误\u故障;
尝试
{
//应用程序的手和粉碎!
if(this->callback)this->callback->OnInfo(resPhase、resStatus、resMessage);
}
捕获(…)
{
rv=NS\u错误\u意外;
ERRF(“nsbackack::从回调运行调用方法OnInfo失败”);
}
返回rv;
}
调用

//*.js
nsDBService.query(“从t中选择*”,函数(阶段、代码、mes){
//某些UI操作或其他db查询
});
问题: 当代码执行如下所示时,应用程序冻结和崩溃:

nsDBService::Query //main thread ok
NS_DispatchToMainThread //main thread
nsResultCallback::Run //main thread
nsIDBCallback::OnInfo //main thread ok
如果代码执行如下所示,则一切正常:

nsDBService::Query //main thread ok
NS_DispatchToMainThread //main thread
nsResultCallback::Run //main thread
nsIDBCallback::OnInfo //main thread ok

nsDBService::Query //main thread ok
NS_DispatchToMainThread //main thread
nsResultCallback::Run //main thread
nsIDBCallback::OnInfo //main thread ok
问题:
当从NS_DispatchToMainThread调用nsIDBCallback,从其他线程调用NS_DispatchToMainThread,然后从主应用程序线程调用NS_DispatchToMainThread时,执行失败,我缺少什么,不明白?或者背景任务的另一种方法是什么?

无法重现,因为您没有提供一个完整的示例,所以请给出以下注释:

nsDBService::Query //main thread ok
NS_DispatchToMainThread //main thread
nsResultCallback::Run //main thread
nsIDBCallback::OnInfo //main thread ok
我注意到的第一件事是
std::vector
的跨线程访问。您在注释中写了一些关于互斥体的内容,所以这可能没问题

nsDBService::Query //main thread ok
NS_DispatchToMainThread //main thread
nsResultCallback::Run //main thread
nsIDBCallback::OnInfo //main thread ok
肯定是错了,存储了指向
nsIDBCallback
的原始指针。XPCOM对象是ref计数的。因此,只要
Query
方法返回,如果没有其他引用,那么底层对象可能是
delete
d,在向量中留下一个悬空指针。我想这就是这里发生的事情! 在线程处理完对象之前,您需要保持对象的活动状态,最好是将其放在某个地方,例如,在

nsDBService::Query //main thread ok
NS_DispatchToMainThread //main thread
nsResultCallback::Run //main thread
nsIDBCallback::OnInfo //main thread ok
PS:原来这是一个有点老的问题,我错过了。。。很抱歉延迟回复:p

nsDBService::Query //main thread ok
NS_DispatchToMainThread //main thread
nsResultCallback::Run //main thread
nsIDBCallback::OnInfo //main thread ok