2017-02-22 71 views
1

我正在测试我使用libuv开发的简单服务器体系结构。 每当服务器从客户端收到一些东西时,它就会按'\ r'分割主体并向所有观察者广播每条消息。多个同时调用uv_write有时不起作用

然后,我用来测试的观察者使用相同的原始消息(回显服务器)调用server-> write()方法。

问题是,每次运行程序时,它都会随机地运行或不运行。

当它不工作,该错误信息是:

Assertion failed: (req->write_index < req->nbufs), function uv__write, file src/unix/stream.c, line 869. Abort trap: 6

全部代码是在这里:https://github.com/ghostec/film

大部分代码是在这个文件中:https://github.com/ghostec/film/blob/master/server/server.cpp

编辑:显然这与uv_queue_work内部调用uv_write的事实有关。由于它们都写入相同的处理程序,因此如果在libuv循环内调用它们时出现故障,则会发生不良情况。不过,我不确定我的评估是否正确。

回答

1

正如documentationuv_write的提到:

注意:内存指向的缓冲区,直到回调函数被调用必须保持有效。这也适用于uv_write2()。

在另一边,这是你的代码:

void Server::write(Message message) { 
    uv_write_t req; 
    uv_buf_t* buf = new uv_buf_t(); 
    buf->base = &(std::vector<char>(message.data.begin(), message.data.end()))[0]; 
    buf->len = message.data.size(); 
    uv_write(&req, message.handle, buf, 1, [](uv_write_t* req, int status) -> void {}); 
    delete buf; 
} 

特别是,该行的代码味道:

buf->base = &(std::vector<char>(message.data.begin(), message.data.end()))[0]; 

还要注意的是,同样适用于uv_buf,因此在回调被称为嗅觉之前删除它。除了怀疑libuv在内部失败之外,我想说你应该对它的执行情况非常感激,即使你不忠于库的需求,在每次使用uv_write时都不会看到问题。


对于您所标记的问题与c++,我建议你使用one of the existing wrappers是正确地管理内存和数据结构为你的引擎盖下。请参阅上述链接中的绑定部分。

+0

我怀疑循环工作的[删除请求](https://github.com/ghostec/film/blob/master/server/server.cpp#L49)并不是一个好主意。 ;-) – skypjack

+0

非常感谢!解决了你指出的错误之后,我仍然有同样的问题。 新功能:https://github.com/ghostec/film/blob/master/server/server.cpp#L36 如果我不在这里使用uv_queue_work https://github.com/ghostec/film/ blob/master/server/server.cpp#L55,只是用观察者(消息)替换整个内部的随机崩溃停止。 –

+0

我建议你从答案中链接的项目中获得灵感。我无法一遍又一遍地查看代码来解决任何问题,我现在正在工作,对不起。 – skypjack