2017-02-22 6 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_write создаются внутри uv_queue_work. Поскольку все они пишут одному обработчику, если они выходят из строя при вызове внутри цикла libuv, происходит что-то плохое. Однако я не уверен, что моя оценка правильная.

ответ

1

Как уже упоминалось в documentation из uv_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 и просто замените всю внутреннюю часть for на наблюдателя (сообщение), случайные сбои прекращаются. –

+0

Я предлагаю вам продолжать вдохновлять проекты, связанные с ответом. Я не могу снова и снова просматривать код, чтобы решить любую проблему, я сейчас работаю, извините. – skypjack

 Смежные вопросы

  • Нет связанных вопросов^_^