2010-07-27 4 views
1

J'ai ma propre DLL qui est injectée dans un autre processus. À partir de l'autre processus, la DLL envoie des messages IPC via boost::message_queue à mon application. J'utilise std :: stringstream pour construire les messages, comme suit:std :: bugs stringstream?

class Client 
{ 
    ... 

    private: 
     template <class T> void AddMessageParameter(const T &m) 
     { 
      _message &lt&lt m &lt&lt "|"; 
     } 

     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 _mq_last_sent_message; 
     boost::shared_ptr<boost::interprocess::message_queue> _mq; 
}; 

Dans la DLL, l'un de la fonction envoie le message suivant en permanence:

AddMessageParameter("CLIENT__TABLE__PLAYER_BANKROLL"); 
AddMessageParameter(window_handle); 
AddMessageParameter(seat); 
AddMessageParameter(s); 

SendMessage(); 

Maintenant, cela produit un message comme CLIENT_TABLE_PLAYER_BANKROLL|00211606|6|€1.28|. Le problème est que, dans tous les quelques milliers de messages, le premier paramètre n'ajoute pas là et le message devient comme 00211606|6|€1.28|

Pourquoi est-ce? Est-ce un bug dans le fichier std :: stringstream ou est-ce que je fais quelque chose de mal peut-être?

Merci d'avance pour toute aide.

EDIT:

Problème résolu. C'était un problème de sécurité des threads. Un mutex simple a résolu ceci.

Répondre

11

Votre code échoue lorsque vous essayez d'envoyer le message le plus long. Par conséquent, je suppose que la cible du message ne lit pas assez vite.

Je pense que votre concept d'essayer 5 fois est défectueux, parce que vous avalez votre message s'il n'a pas été envoyé - et vous ne gérez même pas ce cas d'erreur grave. Personnellement, je vous recommande d'attendre indéfiniment pour envoyer votre message, ou de construire un tampon local de taille saine dans lequel vous travaillez - et si ce tampon est plein, alors vous attendez toujours.

Je recommande également de ne pas manger toutes les exceptions sans en prendre soin. Vous cachez silencieusement les erreurs graves.

En note: Les gens pensent souvent que std :: string a des bogues, ou que le système d'exploitation a des bogues, ou même que le compilateur a des bogues. Laissez-moi vous assurer que ces gens ont si souvent tort dans leur accusation que même le pessimiste le plus défensif dirait qu'ils sont toujours dans l'erreur. Et ceux qui ont raison peuvent le prouver dans des programmes triviaux.

Veuillez excuser mon arrogance.

+5

+1 pour la note de côté – onof

+1

un autre +1 pour la note de côté. –