From: kgv Date: Wed, 19 Jul 2017 09:34:09 +0000 (+0300) Subject: 0028923: Foundation Classes - Message_Messenger::Send() implementation is not thread... X-Git-Tag: V7_2_0_beta~29 X-Git-Url: http://git.dev.opencascade.org/gitweb/?p=occt.git;a=commitdiff_plain;h=983fd6c02b6c273bf4a2f37773a399fe657d8057 0028923: Foundation Classes - Message_Messenger::Send() implementation is not thread-safe Use (Message_SequenceOfPrinters::Iterator instead of accessing sequence elements by index. --- diff --git a/src/Message/FILES b/src/Message/FILES index a19626a9ec..e502c6903c 100755 --- a/src/Message/FILES +++ b/src/Message/FILES @@ -10,7 +10,6 @@ Message_ListIteratorOfListOfMsg.hxx Message_ListOfMsg.hxx Message_Messenger.cxx Message_Messenger.hxx -Message_Messenger.lxx Message_Msg.cxx Message_Msg.hxx Message_Msg.lxx @@ -18,10 +17,8 @@ Message_MsgFile.cxx Message_MsgFile.hxx Message_Printer.cxx Message_Printer.hxx -Message_Printer.lxx Message_PrinterOStream.cxx Message_PrinterOStream.hxx -Message_PrinterOStream.lxx Message_ProgressIndicator.cxx Message_ProgressIndicator.hxx Message_ProgressIndicator.lxx diff --git a/src/Message/Message_Messenger.cxx b/src/Message/Message_Messenger.cxx index da9a9ea8ea..1e44c8b220 100644 --- a/src/Message/Message_Messenger.cxx +++ b/src/Message/Message_Messenger.cxx @@ -13,13 +13,10 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. - #include + #include #include -#include -#include -#include IMPLEMENT_STANDARD_RTTIEXT(Message_Messenger,Standard_Transient) @@ -50,10 +47,15 @@ Message_Messenger::Message_Messenger (const Handle(Message_Printer)& thePrinter) Standard_Boolean Message_Messenger::AddPrinter (const Handle(Message_Printer)& thePrinter) { // check whether printer is already in the list - for (Standard_Integer i=1; i <= myPrinters.Length(); i++) - if ( myPrinters(i) == thePrinter ) + for (Message_SequenceOfPrinters::Iterator aPrinterIter (myPrinters); aPrinterIter.More(); aPrinterIter.Next()) + { + const Handle(Message_Printer)& aPrinter = aPrinterIter.Value(); + if (aPrinter == thePrinter) + { return Standard_False; - // add to the list + } + } + myPrinters.Append (thePrinter); return Standard_True; } @@ -66,12 +68,15 @@ Standard_Boolean Message_Messenger::AddPrinter (const Handle(Message_Printer)& t Standard_Boolean Message_Messenger::RemovePrinter (const Handle(Message_Printer)& thePrinter) { // find printer in the list - for (Standard_Integer i=1; i <= myPrinters.Length(); i++) - if ( myPrinters(i) == thePrinter ) + for (Message_SequenceOfPrinters::Iterator aPrinterIter (myPrinters); aPrinterIter.More(); aPrinterIter.Next()) + { + const Handle(Message_Printer)& aPrinter = aPrinterIter.Value(); + if (aPrinter == thePrinter) { - myPrinters.Remove (i); + myPrinters.Remove (aPrinterIter); return Standard_True; } + } return Standard_False; } @@ -84,12 +89,19 @@ Standard_Integer Message_Messenger::RemovePrinters (const Handle(Standard_Type)& { // remove printers from the list Standard_Integer nb = 0; - for (Standard_Integer i=1; i <= myPrinters.Length(); i++) - if ( myPrinters(i)->IsKind(theType) ) + for (Message_SequenceOfPrinters::Iterator aPrinterIter (myPrinters); aPrinterIter.More();) + { + const Handle(Message_Printer)& aPrinter = aPrinterIter.Value(); + if (!aPrinter.IsNull() && aPrinter->IsKind (theType)) { - myPrinters.Remove (i--); + myPrinters.Remove (aPrinterIter); nb++; } + else + { + aPrinterIter.Next(); + } + } return nb; } @@ -102,12 +114,13 @@ void Message_Messenger::Send (const Standard_CString theString, const Message_Gravity theGravity, const Standard_Boolean putEndl) const { - Standard_Integer nb = myPrinters.Length(); - for (Standard_Integer i = 1; i <= nb; i++) + for (Message_SequenceOfPrinters::Iterator aPrinterIter (myPrinters); aPrinterIter.More(); aPrinterIter.Next()) { - Handle(Message_Printer) aPrinter = myPrinters(i); - if ( ! aPrinter.IsNull() ) - aPrinter->Send ( theString, theGravity, putEndl ); + const Handle(Message_Printer)& aPrinter = aPrinterIter.Value(); + if (!aPrinter.IsNull()) + { + aPrinter->Send (theString, theGravity, putEndl); + } } } @@ -120,12 +133,13 @@ void Message_Messenger::Send (const TCollection_AsciiString& theString, const Message_Gravity theGravity, const Standard_Boolean putEndl) const { - Standard_Integer nb = myPrinters.Length(); - for (Standard_Integer i = 1; i <= nb; i++) + for (Message_SequenceOfPrinters::Iterator aPrinterIter (myPrinters); aPrinterIter.More(); aPrinterIter.Next()) { - Handle(Message_Printer) aPrinter = myPrinters(i); - if ( ! aPrinter.IsNull() ) - aPrinter->Send ( theString, theGravity, putEndl ); + const Handle(Message_Printer)& aPrinter = aPrinterIter.Value(); + if (!aPrinter.IsNull()) + { + aPrinter->Send (theString, theGravity, putEndl); + } } } @@ -138,11 +152,12 @@ void Message_Messenger::Send (const TCollection_ExtendedString& theString, const Message_Gravity theGravity, const Standard_Boolean putEndl) const { - Standard_Integer nb = myPrinters.Length(); - for (Standard_Integer i = 1; i <= nb; i++) + for (Message_SequenceOfPrinters::Iterator aPrinterIter (myPrinters); aPrinterIter.More(); aPrinterIter.Next()) { - Handle(Message_Printer) aPrinter = myPrinters(i); - if ( ! aPrinter.IsNull() ) - aPrinter->Send ( theString, theGravity, putEndl ); + const Handle(Message_Printer)& aPrinter = aPrinterIter.Value(); + if (!aPrinter.IsNull()) + { + aPrinter->Send (theString, theGravity, putEndl); + } } } diff --git a/src/Message/Message_Messenger.hxx b/src/Message/Message_Messenger.hxx index 4d2325f7f5..0779461e04 100644 --- a/src/Message/Message_Messenger.hxx +++ b/src/Message/Message_Messenger.hxx @@ -16,19 +16,17 @@ #ifndef _Message_Messenger_HeaderFile #define _Message_Messenger_HeaderFile -#include -#include - +#include #include #include #include #include #include #include -#include +#include +#include + class Message_Printer; -class TCollection_AsciiString; -class TCollection_ExtendedString; // resolve name collisions with WinAPI headers #ifdef AddPrinter @@ -52,10 +50,9 @@ DEFINE_STANDARD_HANDLE(Message_Messenger, Standard_Transient) //! Note that all these operators use trace level Warning. class Message_Messenger : public Standard_Transient { - + DEFINE_STANDARD_RTTIEXT(Message_Messenger, Standard_Transient) public: - //! Empty constructor; initializes by single printer directed to cout. //! Note: the default messenger is not empty but directed to cout //! in order to protect against possibility to forget defining printers. @@ -81,12 +78,12 @@ public: Standard_EXPORT Standard_Integer RemovePrinters (const Handle(Standard_Type)& theType); //! Returns current sequence of printers - const Message_SequenceOfPrinters& Printers() const; - + const Message_SequenceOfPrinters& Printers() const { return myPrinters; } + //! Returns sequence of printers //! The sequence can be modified. - Message_SequenceOfPrinters& ChangePrinters(); - + Message_SequenceOfPrinters& ChangePrinters() { return myPrinters; } + //! Dispatch a message to all the printers in the list. //! Three versions of string representations are accepted for //! convenience, by default all are converted to ExtendedString. @@ -101,29 +98,91 @@ public: //! See above Standard_EXPORT void Send (const TCollection_ExtendedString& theString, const Message_Gravity theGravity = Message_Warning, const Standard_Boolean putEndl = Standard_True) const; - - - - DEFINE_STANDARD_RTTIEXT(Message_Messenger,Standard_Transient) - -protected: - - - - private: - Message_SequenceOfPrinters myPrinters; - }; +// CString +inline const Handle(Message_Messenger)& operator<< (const Handle(Message_Messenger)& theMessenger, + const Standard_CString theStr) +{ + theMessenger->Send (theStr, Message_Info, Standard_False); + return theMessenger; +} + +// AsciiString +inline const Handle(Message_Messenger)& operator<< (const Handle(Message_Messenger)& theMessenger, + const TCollection_AsciiString& theStr) +{ + theMessenger->Send (theStr, Message_Info, Standard_False); + return theMessenger; +} -#include +// HAsciiString +inline const Handle(Message_Messenger)& operator<< (const Handle(Message_Messenger)& theMessenger, + const Handle(TCollection_HAsciiString)& theStr) +{ + theMessenger->Send (theStr->String(), Message_Info, Standard_False); + return theMessenger; +} +// ExtendedString +inline const Handle(Message_Messenger)& operator<< (const Handle(Message_Messenger)& theMessenger, + const TCollection_ExtendedString& theStr) +{ + theMessenger->Send (theStr, Message_Info, Standard_False); + return theMessenger; +} +// HExtendedString +inline const Handle(Message_Messenger)& operator<< (const Handle(Message_Messenger)& theMessenger, + const Handle(TCollection_HExtendedString)& theStr) +{ + theMessenger->Send (theStr->String(), Message_Info, Standard_False); + return theMessenger; +} +// Integer +inline const Handle(Message_Messenger)& operator<< (const Handle(Message_Messenger)& theMessenger, + const Standard_Integer theVal) +{ + TCollection_AsciiString aStr (theVal); + theMessenger->Send (aStr, Message_Info, Standard_False); + return theMessenger; +} + +// Real +inline const Handle(Message_Messenger)& operator<< (const Handle(Message_Messenger)& theMessenger, + const Standard_Real theVal) +{ + TCollection_AsciiString aStr (theVal); + theMessenger->Send (aStr, Message_Info, Standard_False); + return theMessenger; +} + +// Stream +inline const Handle(Message_Messenger)& operator<< (const Handle(Message_Messenger)& theMessenger, + const Standard_SStream& theStream) +{ + theMessenger->Send (theStream.str().c_str(), Message_Info, Standard_False); + return theMessenger; +} + +// manipulators +inline const Handle(Message_Messenger)& + operator << (const Handle(Message_Messenger)& theMessenger, + const Handle(Message_Messenger)& (*pman) (const Handle(Message_Messenger)&)) +{ + return pman (theMessenger); +} +// endl +inline const Handle(Message_Messenger)& endl (const Handle(Message_Messenger)& theMessenger) +{ + theMessenger->Send ("", Message_Info, Standard_True); + return theMessenger; +} #endif // _Message_Messenger_HeaderFile diff --git a/src/Message/Message_Messenger.lxx b/src/Message/Message_Messenger.lxx deleted file mode 100644 index 7222a4e18f..0000000000 --- a/src/Message/Message_Messenger.lxx +++ /dev/null @@ -1,143 +0,0 @@ -// Created on: 2007-06-29 -// Created by: OCC Team -// Copyright (c) 2007-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#include - -//======================================================================= -//function : GetPrinters -//purpose : -//======================================================================= - -inline const Message_SequenceOfPrinters& Message_Messenger::Printers() const -{ - return myPrinters; -} - -//======================================================================= -//function : GetPrinters -//purpose : -//======================================================================= - -inline Message_SequenceOfPrinters& Message_Messenger::ChangePrinters() -{ - return myPrinters; -} - -//======================================================================= -//function : operator << -//purpose : -//======================================================================= - -#include -#include - -// CString -inline const Handle(Message_Messenger)& - operator << (const Handle(Message_Messenger)& theMessenger, - const Standard_CString theStr) -{ - theMessenger->Send (theStr, Message_Info, Standard_False); - return theMessenger; -} - -// const char* (not the same as const CString which is char const*) -/* -inline const Handle(Message_Messenger)& - operator << (const Handle(Message_Messenger)& theMessenger, - const char* theStr) -{ - theMessenger->Send ((Standard_CString)theStr, Message_Info, Standard_False); - return theMessenger; -} -*/ -// AsciiString -inline const Handle(Message_Messenger)& - operator << (const Handle(Message_Messenger)& theMessenger, - const TCollection_AsciiString& theStr) -{ - theMessenger->Send (theStr, Message_Info, Standard_False); - return theMessenger; -} - -// HAsciiString -inline const Handle(Message_Messenger)& - operator << (const Handle(Message_Messenger)& theMessenger, - const Handle(TCollection_HAsciiString)& theStr) -{ - theMessenger->Send (theStr->String(), Message_Info, Standard_False); - return theMessenger; -} - -// ExtendedString -inline const Handle(Message_Messenger)& - operator << (const Handle(Message_Messenger)& theMessenger, - const TCollection_ExtendedString& theStr) -{ - theMessenger->Send (theStr, Message_Info, Standard_False); - return theMessenger; -} - -// HExtendedString -inline const Handle(Message_Messenger)& - operator << (const Handle(Message_Messenger)& theMessenger, - const Handle(TCollection_HExtendedString)& theStr) -{ - theMessenger->Send (theStr->String(), Message_Info, Standard_False); - return theMessenger; -} - -// Integer -inline const Handle(Message_Messenger)& - operator << (const Handle(Message_Messenger)& theMessenger, - const Standard_Integer theVal) -{ - TCollection_AsciiString aStr (theVal); - theMessenger->Send (aStr, Message_Info, Standard_False); - return theMessenger; -} - -// Real -inline const Handle(Message_Messenger)& - operator << (const Handle(Message_Messenger)& theMessenger, - const Standard_Real theVal) -{ - TCollection_AsciiString aStr (theVal); - theMessenger->Send (aStr, Message_Info, Standard_False); - return theMessenger; -} - -// Stream -inline const Handle(Message_Messenger)& - operator << (const Handle(Message_Messenger)& theMessenger, - const Standard_SStream& theStream) -{ - theMessenger->Send (theStream.str().c_str(), Message_Info, Standard_False); - return theMessenger; -} - -// manipulators -inline const Handle(Message_Messenger)& - operator << (const Handle(Message_Messenger)& theMessenger, - const Handle(Message_Messenger)& (*pman) (const Handle(Message_Messenger)&)) -{ - return pman (theMessenger); -} - -// endl -inline const Handle(Message_Messenger)& endl (const Handle(Message_Messenger)& theMessenger) -{ - theMessenger->Send ("", Message_Info, Standard_True); - return theMessenger; -} diff --git a/src/Message/Message_Printer.cxx b/src/Message/Message_Printer.cxx index d906e79a0e..8ed2b87e6a 100644 --- a/src/Message/Message_Printer.cxx +++ b/src/Message/Message_Printer.cxx @@ -15,7 +15,6 @@ #include -#include #include #include diff --git a/src/Message/Message_Printer.hxx b/src/Message/Message_Printer.hxx index 56258f39c0..e7e70ddfbd 100644 --- a/src/Message/Message_Printer.hxx +++ b/src/Message/Message_Printer.hxx @@ -36,18 +36,17 @@ DEFINE_STANDARD_HANDLE(Message_Printer, Standard_Transient) //! level, which can be used by printer to decide either to process a message or ignore it. class Message_Printer : public Standard_Transient { - + DEFINE_STANDARD_RTTIEXT(Message_Printer, Standard_Transient) public: - //! Return trace level used for filtering messages; //! messages with lover gravity will be ignored. - Message_Gravity GetTraceLevel() const; - + Message_Gravity GetTraceLevel() const { return myTraceLevel; } + //! Set trace level used for filtering messages. //! By default, trace level is Message_Info, so that all messages are output - void SetTraceLevel (const Message_Gravity theTraceLevel); - + void SetTraceLevel (const Message_Gravity theTraceLevel) { myTraceLevel = theTraceLevel; } + //! Send a string message with specified trace level. //! The parameter theToPutEol specified whether end-of-line should be added to the end of the message. //! This method must be redefined in descentant. @@ -63,32 +62,15 @@ public: //! Default implementation calls first method Send(). Standard_EXPORT virtual void Send (const TCollection_AsciiString& theString, const Message_Gravity theGravity, const Standard_Boolean theToPutEol) const; - - - - DEFINE_STANDARD_RTTIEXT(Message_Printer,Standard_Transient) - protected: - //! Empty constructor with Message_Info trace level Standard_EXPORT Message_Printer(); - Message_Gravity myTraceLevel; - - -private: - - +protected: + Message_Gravity myTraceLevel; }; - -#include - - - - - #endif // _Message_Printer_HeaderFile diff --git a/src/Message/Message_Printer.lxx b/src/Message/Message_Printer.lxx deleted file mode 100644 index fe3034aeb1..0000000000 --- a/src/Message/Message_Printer.lxx +++ /dev/null @@ -1,36 +0,0 @@ -// Created on: 2007-06-28 -// Created by: Pavel TELKOV -// Copyright (c) 2007-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#include - -//======================================================================= -//function : GetTraceLevel -//purpose : -//======================================================================= - -inline Message_Gravity Message_Printer::GetTraceLevel() const -{ - return myTraceLevel; -} - -//======================================================================= -//function : SetTraceLevel -//purpose : -//======================================================================= - -inline void Message_Printer::SetTraceLevel (const Message_Gravity theTraceLevel) -{ - myTraceLevel = theTraceLevel; -} diff --git a/src/Message/Message_PrinterOStream.cxx b/src/Message/Message_PrinterOStream.cxx index d77e503978..b822c0f48b 100644 --- a/src/Message/Message_PrinterOStream.cxx +++ b/src/Message/Message_PrinterOStream.cxx @@ -13,12 +13,9 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. - -#include #include -#include -#include -#include + +#include #include #include @@ -68,8 +65,8 @@ Message_PrinterOStream::Message_PrinterOStream (const Standard_CString theFileNa aFileName.ChangeAll ('/', '\\'); #endif - std::ofstream* aFile = new std::ofstream (aFileName.ToCString(), - (theToAppend ? (std::ios_base::app | std::ios_base::out) : std::ios_base::out)); + std::ofstream* aFile = new std::ofstream(); + OSD_OpenStream (*aFile, aFileName.ToCString(), (theToAppend ? (std::ios_base::app | std::ios_base::out) : std::ios_base::out)); if (aFile->is_open()) { myStream = (Standard_OStream* )aFile; @@ -142,16 +139,6 @@ void Message_PrinterOStream::Send (const TCollection_ExtendedString &theString, const Message_Gravity theGravity, const Standard_Boolean putEndl) const { - // Note: the string might need to be converted to Ascii - if ( myUseUtf8 ) { - char* astr = new char[theString.LengthOfCString()+1]; - theString.ToUTF8CString (astr); - Send ( astr, theGravity, putEndl ); - delete [] astr; - astr = 0; - } - else { - TCollection_AsciiString aStr ( theString, '?' ); - Send ( aStr.ToCString(), theGravity, putEndl ); - } + TCollection_AsciiString aStr (theString, myUseUtf8 ? Standard_Character(0) : '?'); + Send (aStr.ToCString(), theGravity, putEndl); } diff --git a/src/Message/Message_PrinterOStream.hxx b/src/Message/Message_PrinterOStream.hxx index 01c6a1c894..e593f9441b 100644 --- a/src/Message/Message_PrinterOStream.hxx +++ b/src/Message/Message_PrinterOStream.hxx @@ -16,18 +16,9 @@ #ifndef _Message_PrinterOStream_HeaderFile #define _Message_PrinterOStream_HeaderFile -#include -#include - -#include -#include #include -#include -#include +#include #include -class TCollection_AsciiString; -class TCollection_ExtendedString; - class Message_PrinterOStream; DEFINE_STANDARD_HANDLE(Message_PrinterOStream, Message_Printer) @@ -37,9 +28,8 @@ DEFINE_STANDARD_HANDLE(Message_PrinterOStream, Message_Printer) //! or file stream maintained internally (depending on constructor). class Message_PrinterOStream : public Message_Printer { - + DEFINE_STANDARD_RTTIEXT(Message_PrinterOStream, Message_Printer) public: - //! Empty constructor, defaulting to cout Standard_EXPORT Message_PrinterOStream(const Message_Gravity theTraceLevel = Message_Info); @@ -58,15 +48,15 @@ public: { Close(); } - + //! Returns option to convert non-Ascii symbols to UTF8 encoding - Standard_Boolean GetUseUtf8() const; + Standard_Boolean GetUseUtf8() const { return myUseUtf8; } //! Sets option to convert non-Ascii symbols to UTF8 encoding - void SetUseUtf8 (const Standard_Boolean useUtf8); - + void SetUseUtf8 (const Standard_Boolean useUtf8) { myUseUtf8 = useUtf8; } + //! Returns reference to the output stream - Standard_OStream& GetStream() const; + Standard_OStream& GetStream() const { return *(Standard_OStream*)myStream; } //! Puts a message to the current stream //! if its gravity is equal or greater @@ -85,30 +75,12 @@ public: //! option is set, else replaced by symbols '?' Standard_EXPORT virtual void Send (const TCollection_ExtendedString& theString, const Message_Gravity theGravity, const Standard_Boolean putEndl = Standard_True) const Standard_OVERRIDE; - - - DEFINE_STANDARD_RTTIEXT(Message_PrinterOStream,Message_Printer) - -protected: - - - - private: - Standard_Address myStream; Standard_Boolean myIsFile; Standard_Boolean myUseUtf8; - }; - -#include - - - - - #endif // _Message_PrinterOStream_HeaderFile diff --git a/src/Message/Message_PrinterOStream.lxx b/src/Message/Message_PrinterOStream.lxx deleted file mode 100644 index 754e86d29e..0000000000 --- a/src/Message/Message_PrinterOStream.lxx +++ /dev/null @@ -1,46 +0,0 @@ -// Created on: 2007-06-28 -// Created by: Pavel TELKOV -// Copyright (c) 2007-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#include - -//======================================================================= -//function : GetUseUtf8 -//purpose : -//======================================================================= - -inline Standard_Boolean Message_PrinterOStream::GetUseUtf8() const -{ - return myUseUtf8; -} - -//======================================================================= -//function : SetUseUtf8 -//purpose : -//======================================================================= - -inline void Message_PrinterOStream::SetUseUtf8 (const Standard_Boolean useUtf8) -{ - myUseUtf8 = useUtf8; -} - -//======================================================================= -//function : GetStream -//purpose : -//======================================================================= - -inline Standard_OStream& Message_PrinterOStream::GetStream () const -{ - return *(Standard_OStream*)myStream; -}