ROSE  0.9.6a
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RTS_Message Class Reference

Support for messages in a multi-threaded program. More...

#include <threadSupport.h>

Collaboration diagram for RTS_Message:

Classes

class  Prefix
 The Prefix class is used to generate prefix text for every line of output. More...
 

Public Member Functions

 RTS_Message (FILE *f, Prefix *p)
 Creates a new message object. More...
 
 ~RTS_Message ()
 
void set_file (FILE *f)
 Sets the file handle to use for subsequent messages. More...
 
FILE * get_file () const
 Returns the file handle being used for messages. More...
 
RTS_Messagemultipart (const std::string &name, const char *fmt,...) __attribute__((format(printf
 Begins a multi-part message. More...
 
RTS_Message RTS_Messagemore (const char *fmt,...) __attribute__((format(printf
 Continues a multi-part message. More...
 
RTS_Message RTS_Message void multipart_end ()
 Terminates a multi-part message. More...
 
RTS_Messagemesg (const char *fmt,...) __attribute__((format(printf
 Outputs a single-line message. More...
 
RTS_Message RTS_Messagebrief (const char *fmt,...) __attribute__((format(printf
 Outputs a short note. More...
 
RTS_Message RTS_Message void brief_begin (const char *fmt,...) __attribute__((format(printf
 Obtains the lock and starts a brief message. More...
 
RTS_Message RTS_Message void void brief_end (const char *fmt,...) __attribute__((format(printf
 Complets a brief message and releases the lock. More...
 
RTS_Message RTS_Message void
void int 
lock ()
 Obtain the message class lock. More...
 
int unlock (bool sol=true)
 Releases the message class lock. More...
 

Private Member Functions

 RTS_Message ()
 
RTS_Messageoperator= (RTS_Message &)
 
void ctor ()
 Constructor helper. More...
 
void dtor ()
 Desctructor helper. More...
 
void terminate ()
 Terminate line if necessary. More...
 
void prefix ()
 Print line prefix regardless of "sol" state. More...
 
void output_lines (const char *s)
 Output one or more lines, prefix as necessary. More...
 
void format (const char *fmt, va_list, va_list)
 Formats a message into the "buffer" data member. More...
 

Private Attributes

FILE * f
 Optional file to which we write messages. More...
 
Prefixp
 Optional line prefix functor. More...
 
char * buffer
 Heap-allocated buffer for holding formatted message. More...
 
size_t bufsz
 Allocated size of "buffer". More...
 
std::string name
 Name supplied to latest multipart() invocation. More...
 
bool interrupted
 True if multi-part message was interrupted. More...
 

Static Private Attributes

static RTS_rwlock_t rwlock
 Class-wide rwlock used as a recursive mutex. More...
 
static RTS_Messagein_multi
 Non-null when we inside a multi-line mesg (not between lines). More...
 
static bool sol
 True when we're at the start of a line. More...
 

Detailed Description

Support for messages in a multi-threaded program.

This class helps messages (debugging, info, etc) produced by a multi-threaded application into meaningful output. A typical problem one encounters is that messages, especially multi line messages produced over an indeterminate period of time (e.g., due to intervening blocking calls) get interleaved with messages from other threads and become nonsensical. This class makes such messages understandable, provided all messages are generated with this class.

Note: For the sake of determining when two messages interfere with each other, we assume that all files are sending output to the same place. This works fine in most cases where messages are being sent to stdout and/or stderr, which often both appear in the terminal, but can result in extraneous multi-part interrupt/resume phrases when output really is going to different places.

Definition at line 579 of file threadSupport.h.

Constructor & Destructor Documentation

RTS_Message::RTS_Message ( FILE *  f,
Prefix p 
)
inline

Creates a new message object.

Message objects are generally not safe to be called from multiple threads. Instead, each thread creates its own object as necessary on the stack, and destroys it when finished (usually implicitly). A single object can handle at most one outstanding multi-part message; it can, however, output multiple messages sequentially.

The provided file handle is used for all output by this object. A null file handle is permitted, in which case the output methods will become no-ops.

In order to associate each line of message output with a particular thread, each line of output begins with a prefix. The prefix is generated by the supplied, optional functor invoked with one argument: the file handle specified in the constructor.

Definition at line 600 of file threadSupport.h.

References ctor().

RTS_Message::~RTS_Message ( )
inline

Definition at line 605 of file threadSupport.h.

References dtor().

RTS_Message::RTS_Message ( )
inlineprivate

Definition at line 719 of file threadSupport.h.

Member Function Documentation

void RTS_Message::set_file ( FILE *  f)
inline

Sets the file handle to use for subsequent messages.

A null pointer disables output.

Definition at line 610 of file threadSupport.h.

References f.

FILE* RTS_Message::get_file ( ) const
inline

Returns the file handle being used for messages.

Returns null if messages are disabled for this object.

Definition at line 615 of file threadSupport.h.

References f.

RTS_Message& RTS_Message::multipart ( const std::string &  name,
const char *  fmt,
  ... 
)

Begins a multi-part message.

The content of a multi-part message is created by an initial call to multipart() and zero or more subsequent calls to more(). The concatentation of these calls may result in one or more lines of text, each of which is introduced by invoking the optional prefix generator supplied in the constructor. The lines of the message need not have a one-to-one correspondence with the multipart() and more() invocations.

If some other message is output via method invocations on some other RTS_Message object while this object's multi-part message is in the middle of a line (and between calls to multipart() or more()), this message is considered to be in an interrupted state. When a multi-part message is interrupted, the phrase " <%s continued below>\n" is output to terminate the line, where "%s" is the message name provided as the first argument to multipart(). When an interrupted message is resumed by a later call to more(), the additional text will be introduced by first invoking the optional prefix generator, then writing the phrase "<%s resumed> ". If a name is not provided then the continued and resumed phrases are not emitted.

The fmt and following arguments are the same as for printf().

No output is produced and the lock is not acquired if the file pointer provided in the constructor is a null pointer.

No output is produced if the message is zero length.

The return value is always this object, allowing most of these methods to be strung together in a single expression.

RTS_Message RTS_Message& RTS_Message::more ( const char *  fmt,
  ... 
)

Continues a multi-part message.

Each new line in the message begins with a prefix generated by invoking the optional prefix functor supplied in the constructor. If this multi-part message was interrupted since the last output, then the phrase "<%s resumed> " is printed first, where "%s" is the name supplied to the previous multipart() invocation. If no name was supplied then no resumed phrase is emitted.

The fmt and following arguments are the same as for printf().

No output is produced and the lock is not acquired if the file pointer provided in the constructor is a null pointer.

No output is produced if the message is zero length.

The return value is always this object, allowing most of these methods to be strung together in a single expression.

RTS_Message RTS_Message void RTS_Message::multipart_end ( )

Terminates a multi-part message.

This doesn't generally need to be called. If not called, and brief() is used after the logical end of the multipart messsage, then the next call to multipart() or mesg() will result in a continuation phrase.

RTS_Message& RTS_Message::mesg ( const char *  fmt,
  ... 
)

Outputs a single-line message.

This method acquires the class lock, outputs the specified message, outputs a line feed if necessary, and then releases the lock. The message may consist of multiple lines, and each line will be prefixed by invoking the optional prefix functor specified in the constructor. This message is allowed to interrupt other multi-part messages that might be under construction from either this object, or another object perhaps even in another thread.

The fmt and following arguments are the same as for printf().

No output is produced and the lock is not acquired if the file pointer provided in the constructor is a null pointer.

No output is produced if the message is zero length.

The return value is always this object, allowing most of these methods to be strung together in a single expression.

RTS_Message RTS_Message& RTS_Message::brief ( const char *  fmt,
  ... 
)

Outputs a short note.

A note is a single-line (usually only a few words) phrase that will be output enclosed in square brackets and no white space on either side (unless white space was already produced by some other method). If this message interrupts a multi-part message from this same object then only the square brackets and message are printed; otherwise the optional, constructor-supplied prefix functor is invoked to provide context information between the opening square bracket and the message. When this kind of message interrupts a multi-part message, this message is output in-line with the multi-part and is not considered to truly interrupt the multi-part message.

The fmt and following arguments are the same as for printf().

No output is produced and the lock is not acquired if the file pointer provided in the constructor is a null pointer.

No output is produced if the message is zero length.

The return value is always this object, allowing most of these methods to be strung together in a single expression.

RTS_Message RTS_Message void RTS_Message::brief_begin ( const char *  fmt,
  ... 
)

Obtains the lock and starts a brief message.

The lock is released by calling brief_end(). This method is provided for situations when a brief message cannot be specified in a single format, or when output requires functions that are not part of this class.

RTS_Message RTS_Message void void RTS_Message::brief_end ( const char *  fmt,
  ... 
)

Complets a brief message and releases the lock.

This must be called once for each brief_begin() invocation.

RTS_Message RTS_Message void void int RTS_Message::lock ( )

Obtain the message class lock.

Although all of the message-producing methods automatically obtain a class lock to prevent other threads from interfering, it is sometimes useful to explicitly obtain the lock. For instance, to produce specially formatted multi-line output using plain old printf and friends, one would obtain the lock, produce output, and then release the lock. The lock should be held for a short amount of time since it precludes other threads from producing messages.

The lock is recursive; it must be unlocked the same number of times it was locked. The normal message producing methods of this class may be called while the lock is held.

Returns zero on success; error number on failure.

int RTS_Message::unlock ( bool  sol = true)

Releases the message class lock.

This should be called once for each time lock() was called. When the lock is released, we need to also indicate whether the output cursor is at the start of a line; sol should be true only at the start of a line.

Returns zero on success; error number on failure.

RTS_Message& RTS_Message::operator= ( RTS_Message )
inlineprivate

Definition at line 720 of file threadSupport.h.

void RTS_Message::ctor ( )
private

Constructor helper.

Referenced by RTS_Message().

void RTS_Message::dtor ( )
private

Desctructor helper.

Referenced by ~RTS_Message().

void RTS_Message::terminate ( )
private

Terminate line if necessary.

void RTS_Message::prefix ( )
private

Print line prefix regardless of "sol" state.

void RTS_Message::output_lines ( const char *  s)
private

Output one or more lines, prefix as necessary.

void RTS_Message::format ( const char *  fmt,
va_list  ,
va_list   
)
private

Formats a message into the "buffer" data member.

Member Data Documentation

RTS_rwlock_t RTS_Message::rwlock
staticprivate

Class-wide rwlock used as a recursive mutex.

Definition at line 728 of file threadSupport.h.

RTS_Message* RTS_Message::in_multi
staticprivate

Non-null when we inside a multi-line mesg (not between lines).

Definition at line 729 of file threadSupport.h.

bool RTS_Message::sol
staticprivate

True when we're at the start of a line.

Definition at line 730 of file threadSupport.h.

FILE* RTS_Message::f
private

Optional file to which we write messages.

Definition at line 732 of file threadSupport.h.

Referenced by get_file(), and set_file().

Prefix* RTS_Message::p
private

Optional line prefix functor.

Definition at line 733 of file threadSupport.h.

char* RTS_Message::buffer
private

Heap-allocated buffer for holding formatted message.

Definition at line 734 of file threadSupport.h.

size_t RTS_Message::bufsz
private

Allocated size of "buffer".

Definition at line 735 of file threadSupport.h.

std::string RTS_Message::name
private

Name supplied to latest multipart() invocation.

Definition at line 736 of file threadSupport.h.

bool RTS_Message::interrupted
private

True if multi-part message was interrupted.

Definition at line 737 of file threadSupport.h.


The documentation for this class was generated from the following file: