std::stringstream bugs?
I've got my own DLL which is being injected into another process. From the other process, the DLL sends IPC messages via boost::message_queue to my application. I'm using std::stringstream to construct the messages, as following:
class Client
{
...
private:
template <class T> void AddMessageParameter(const T &m)
{
_message << m << "|";
}
void SendMessage()
{
if (_mq && _message.str().length() < 1024) {
// Do not send the same message again.
if (_mq_last_sent_message != _message.str()) {
_mq_last_sent_message = _message.str();
try {
unsigned int tries = 0;
// Try send the message five times before giving up.
do {
if (_mq->try_send(_mq_last_sent_message.c_str(), _mq_last_sent_message.length(), 0))
tries = 5;
else
::Sleep(128);
++tries;
} while (tries < 5);
} catch (...) {
// TODO: Add log4cxx logging here for errors...
}
}
}
// Clear the message for a new one.
_message.seekp(0);
_message.clear();
_message.str(std::string());
}
private:
std::stringstream _message;
std::string _m开发者_StackOverflowq_last_sent_message;
boost::shared_ptr<boost::interprocess::message_queue> _mq;
};
In the DLL, one of the function sends the following message constantly:
AddMessageParameter("CLIENT__TABLE__PLAYER_BANKROLL");
AddMessageParameter(window_handle);
AddMessageParameter(seat);
AddMessageParameter(s);
SendMessage();
Now this produces a message like CLIENT_TABLE_PLAYER_BANKROLL|00211606|6|€1.28|
. The problem is, that in every few thousand messages, the first parameter doesn't add there and the message becomes like 00211606|6|€1.28|
Why is that? Is this some bug in the std::stringstream or am I doing something wrong perhaps?
Thanks in advance for any help.
EDIT:
Problem solved. This was an issue of thread safeness. A simple mutex solved this.
Your code fails when trying to send the longest message. Therefore I assume that the message target is not reading fast enough.
I think your concept of trying 5 times is flawed, because you swallow your message if it didn't got sent - and you don't even handle this serious error case. Personally I recommend to either wait forever to send your message, or build a sane sized local buffer which you work of - and if this buffer is full, then you wait forever.
I also recommend that you don't eat all exceptions without caring for them. You silently hide serious errors.
As a side note: People often think that std::string has bugs, or that the OS has bugs, or even that the compiler has bugs. Let me assure you that these people are so often wrong in their accusation that even the most defensive pessimist would say that they are always wrong. And those who are right can prove it in trivial programs.
Please excuse my arrogance.
精彩评论