ROSE
0.9.6a
|
Support for messages in a multi-threaded program. More...
#include <threadSupport.h>
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_Message & | multipart (const std::string &name, const char *fmt,...) __attribute__((format(printf |
Begins a multi-part message. More... | |
RTS_Message RTS_Message & | more (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_Message & | mesg (const char *fmt,...) __attribute__((format(printf |
Outputs a single-line message. More... | |
RTS_Message RTS_Message & | brief (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_Message & | operator= (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... | |
Prefix * | p |
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_Message * | in_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... | |
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.
|
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().
|
inline |
Definition at line 605 of file threadSupport.h.
References dtor().
|
inlineprivate |
Definition at line 719 of file threadSupport.h.
|
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.
|
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.
|
inlineprivate |
Definition at line 720 of file threadSupport.h.
|
private |
Constructor helper.
Referenced by RTS_Message().
|
private |
Desctructor helper.
Referenced by ~RTS_Message().
|
private |
Terminate line if necessary.
|
private |
Print line prefix regardless of "sol" state.
|
private |
Output one or more lines, prefix as necessary.
|
private |
Formats a message into the "buffer" data member.
|
staticprivate |
Class-wide rwlock used as a recursive mutex.
Definition at line 728 of file threadSupport.h.
|
staticprivate |
Non-null when we inside a multi-line mesg (not between lines).
Definition at line 729 of file threadSupport.h.
|
staticprivate |
True when we're at the start of a line.
Definition at line 730 of file threadSupport.h.
|
private |
Optional file to which we write messages.
Definition at line 732 of file threadSupport.h.
Referenced by get_file(), and set_file().
|
private |
Optional line prefix functor.
Definition at line 733 of file threadSupport.h.
|
private |
Heap-allocated buffer for holding formatted message.
Definition at line 734 of file threadSupport.h.
|
private |
Allocated size of "buffer".
Definition at line 735 of file threadSupport.h.
|
private |
Name supplied to latest multipart() invocation.
Definition at line 736 of file threadSupport.h.
|
private |
True if multi-part message was interrupted.
Definition at line 737 of file threadSupport.h.