Vault
4.1
|
VThread is class that provides an easy way to create a thread of execution. More...
#include <vthread.h>
Public Types | |
typedef void *(* | threadMainFunction )(void *param) |
Public Member Functions | |
VThread (const VString &name, const VString &loggerName, bool deleteSelfAtEnd, bool createDetached, VManagementInterface *manager) | |
Constructs the thread object in stopped state. | |
virtual | ~VThread () |
Destructor. | |
virtual void | start () |
Starts the thread by creating whatever OS-specific resources are necessary, and invoking the thread main, resulting in the VThread subclass' run() method being called. | |
virtual void | stop () |
Stops the thread by setting its mIsRunning flag to false; it is up to the thread's own code to look at this flag and return from its run() method. | |
virtual void | run ()=0 |
Override required in each VThread subclass, run() does whatever the thread is designed to do, and returns when the thread has completed its task or detects that isRunning() returns false. | |
VThreadID_Type | threadID () const |
Returns the underlying OS thread ID. | |
bool | isRunning () const |
Returns true if the thread should still be running, false if it has been set to stop and should return from its run() method. | |
bool | join () |
Blocks the calling thread until this VThread has completed. | |
bool | getDeleteAtEnd () const |
Returns the value of the "delete at end" property. | |
VManagementInterface * | getManagementInterface () const |
Returns the thread's management interface object (which may be NULL). | |
const VString & | getName () const |
Returns the thread name (useful for debugging). | |
void | setName (const VString &threadName) |
Sets the thread name (useful for debugging). | |
const VString & | getLoggerName () const |
Returns the thread's logger name (useful for emitting to a named logger). | |
Static Public Member Functions | |
static int | userMain (int argc, char **argv) |
This function is really just a convenience definition; if you want to separate your actual main (for example, in your system exception handling code) from your application specific main, this allows you a standard API through which to decouple them. | |
static void * | userThreadMain (void *arg) |
This function is called as the main function for each thread; you must call through to VThread::threadMain(), but if desired you can wrap this with system exception handling to catch crashes and report them. | |
static void | logStackCrawl (const VString &headerMessage, VNamedLoggerPtr logger, bool verbose) |
This function is available whenever a stack crawl of the current thread location should be logged; it is called the VMemoryTracker module when specified, by the VLogger when configured to do so, and any time you want to, such as when handling a crash in your system exception handler. | |
static void * | threadMain (void *arg) |
The main function that invokes the thread's run() and cleans up when it returns. | |
static void | getThreadsInfo (VBentoNode &bento) |
Returns a Bento data hierarchy describing the set of threads existent at the time of the call. | |
static VString | getThreadName (VThreadID_Type threadID) |
Returns the name of the VThread specified by thread id, if it exists. | |
static void | stopThread (VThreadID_Type threadID) |
Calls stop() on a VThread specified by thread id, if it exists. | |
static void | threadCreate (VThreadID_Type *threadID, bool createDetached, threadMainFunction threadMainProcPtr, void *threadArgument) |
Starts up a new running thread. | |
static void | threadExit () |
Terminates the current thread. | |
static bool | threadJoin (VThreadID_Type threadID, void **value) |
Blocks the calling thread until the specified thread ends. | |
static void | threadDetach (VThreadID_Type threadID) |
Marks the specified thread's storage to be reclaimed when the thread terminates. | |
static VThreadID_Type | threadSelf () |
Returns the ID of the currently executing thread (the caller's thread). | |
static VThread * | getCurrentThread () |
Returns the current thread's VThread. | |
static VString | getCurrentThreadName () |
This is a preferred alternative to getCurrentThread()->getName() to handle the case where it is called from a thread that was not created with a VThread. | |
static bool | setPriority (int nice) |
Sets the current thread's priority, specifying the Unix nice level. | |
static void | sleep (const VDuration &interval) |
Blocks the current thread for a specified number of milliseconds. | |
static void | yield () |
Yields to other threads. | |
Static Public Attributes | |
static const bool | kDeleteSelfAtEnd = true |
The thread main deletes the VThread at end. | |
static const bool | kDontDeleteSelfAtEnd = false |
The thread main does not delete the VThread at end. | |
static const bool | kCreateThreadDetached = true |
The thread will be created in detached state. | |
static const bool | kCreateThreadJoinable = false |
The thread will be created in joinable state. | |
Protected Attributes | |
bool | mIsDeleted |
For debugging purposes it's useful to detect when an attempt is made to delete a thread twice. | |
VString | mName |
For debugging purposes it's very useful to give each thread a name. | |
VString | mLoggerName |
The logger name which we will use when emitting log output. | |
bool | mDeleteAtEnd |
True if threadMain should delete this obj when it returns from run(). | |
bool | mCreateDetached |
True if the thread is created in detached state. | |
VManagementInterface * | mManager |
The VManagementInterface that manages us, or NULL. | |
VThreadID_Type | mThreadID |
The OS-specific thread ID value. | |
volatile bool | mIsRunning |
The running state of the thread (. |
VThread is class that provides an easy way to create a thread of execution.
To start a thread, simply instantiate a VThread (well, actually a subclass of VThread that contains the desired code), and call its start() method. The start() method actually invokes the thread's main function, which in turn invokes the VThread object's run() method, which runs to completion.
If you want to block while a thread is alive, you call the VThread object's join() method. This is typically used to have a server that creates a bunch of threads and then runs until they have all completed or been killed; the server's main thread simply joins to each thread, and this causes it to block on each join() call until that thread has finished. This is far better than cycling through a while loop waiting until you notice that all of your thread objects have been removed. Pass kCreateThreadJoinable for createDetached in the constructor to make the thread joinable.
There is no safe way to remotely "force-kill" another thread. You can only stop() it and let it notice that it has been stopped. As noted above, if you need to wait until thread x has completed, call x->join(). Of course, if the other thread is calling both x->stop() and x->join(), it must call x->stop() first because x->join() blocks until thread x has been completed, and if you call x->join() first, you will never reach your call to x->stop().
There are two typical reasons why you would want to stop a thread, and you need to design such threads to be stoppable:
1. A socket listener thread should be stoppable so that you can disable the service on the socket without bringing down the entire server and the ability to remotely re-enable the service. This is easily accomplished by having the listener thread use a timeout value for accept(), and check the isRunning() property before cycling through to accept again. The timeout value you use will become the latency of the disabling action.
2. A long-running background operation in the UI should often be stoppable via a progress dialog with a cancel button. This is easily accomplished by having the operation's thread periodically check the isRunning() property and cleanly end when it detects that it has been stopped. If the operation is primarily a network transfer or file i/o operation, this can often be done in the loop that reads or writes a chunk of data at a time, when it updates the progress information.
VThread::VThread | ( | const VString & | name, |
const VString & | loggerName, | ||
bool | deleteSelfAtEnd, | ||
bool | createDetached, | ||
VManagementInterface * | manager | ||
) |
Constructs the thread object in stopped state.
name | a name for the thread, useful for debugging purposes |
loggerName | the logger name which we will use when emitting log output. |
deleteSelfAtEnd | true if threadMain() should delete this obj when run() completes; pass kDeleteSelfAtEnd or kDontDeleteSelfAtEnd. If you use kDeleteSelfAtEnd then you need to be careful not to reference the VThread while it is destructing (for example, by joining to it in a non-threadsafe way); if you use kDontDeleteSelfAtEnd, you need to delete the VThread after it has finished running. |
createDetached | true to create the thread in detached state; false if not. Generally, if you aren't joining to a thread, it should be detached, and vice-versa. If a non-detached, non-joined thread ends, it will leak system resources (depending on the platform implementation). |
manager | the object that receives notifications for this thread, or NULL |
Definition at line 64 of file vthread.cpp.
static int VThread::userMain | ( | int | argc, |
char ** | argv | ||
) | [static] |
This function is really just a convenience definition; if you want to separate your actual main (for example, in your system exception handling code) from your application specific main, this allows you a standard API through which to decouple them.
argc | the number of strings in the argv array |
argv | an array of nul-terminated arg strings |
static void* VThread::userThreadMain | ( | void * | arg | ) | [static] |
This function is called as the main function for each thread; you must call through to VThread::threadMain(), but if desired you can wrap this with system exception handling to catch crashes and report them.
arg | the thread argument (actually the VThread pointer) |
void VThread::logStackCrawl | ( | const VString & | headerMessage, |
VNamedLoggerPtr | logger, | ||
bool | verbose | ||
) | [static] |
This function is available whenever a stack crawl of the current thread location should be logged; it is called the VMemoryTracker module when specified, by the VLogger when configured to do so, and any time you want to, such as when handling a crash in your system exception handler.
If the target environment does not support obtaining the stack crawl, this function can just log nothing, or can log a string indicating so.
headerMessage | if not empty, a header message to label the log output |
logger | the logger to write to all output to; if NULL then the implementation may just write to the console or some predefined file |
verbose | false will restrict output to just the function names, avoiding all annotation, registers, etc. so just the fucntion names are logged |
Definition at line 249 of file vthread.cpp.
References VString::chars().
virtual void VThread::run | ( | ) | [pure virtual] |
Override required in each VThread subclass, run() does whatever the thread is designed to do, and returns when the thread has completed its task or detects that isRunning() returns false.
If the thread is designed to be stoppable from another thread, then its run() method must check the isRunning() property periodically and return when the property becomes false.
Implemented in VSocketConnectionStrategyThreadedRunner, VSocketConnectionStrategyThreadedWorker, VForeignThread, VMainThread, VListenerThread, VMessageOutputThread, VMessageInputThread, and VStandinThread.
VThreadID_Type VThread::threadID | ( | ) | const |
Returns the underlying OS thread ID.
On each OS this type is suitable for supplying to OS-specific thread functions.
Definition at line 105 of file vthread.cpp.
References mThreadID.
bool VThread::isRunning | ( | ) | const |
Returns true if the thread should still be running, false if it has been set to stop and should return from its run() method.
Also returns false during the initialization time between instantiation and when run() is invoked.
Definition at line 109 of file vthread.cpp.
References mIsRunning.
bool VThread::join | ( | ) |
Blocks the calling thread until this VThread has completed.
Definition at line 113 of file vthread.cpp.
References mIsRunning, mThreadID, NULL, and threadJoin().
bool VThread::getDeleteAtEnd | ( | ) | const |
Returns the value of the "delete at end" property.
If this property is true, then the thread main function will delete the VThread object when it has completed.
Definition at line 123 of file vthread.cpp.
References mDeleteAtEnd.
VManagementInterface * VThread::getManagementInterface | ( | ) | const |
Returns the thread's management interface object (which may be NULL).
Definition at line 127 of file vthread.cpp.
References mManager.
const VString& VThread::getName | ( | ) | const [inline] |
void VThread::setName | ( | const VString & | threadName | ) | [inline] |
Sets the thread name (useful for debugging).
Sometimes you don't have all the information you need to generate a good name at time of construction, so you can set it later by calling this method. If you want the name to be really useful when debugging (or looking at log files) as a unique identifier (to tell threads apart), make it unique; one way would be to use the object's address (e.g., VSTRING_FORMAT("0x%08X", aThread)); if the thread is related to a socket, a more useful name would be a prefix plus the client IP and port (e.g., "INPUT:127.0.0.1:3922" for an input thread).
threadName | a name for this thread |
Definition at line 279 of file vthread.h.
References mName.
const VString& VThread::getLoggerName | ( | ) | const [inline] |
Returns the thread's logger name (useful for emitting to a named logger).
Definition at line 284 of file vthread.h.
References mLoggerName.
void * VThread::threadMain | ( | void * | arg | ) | [static] |
The main function that invokes the thread's run() and cleans up when it returns.
arg | we use this parameter for the VThread object pointer |
Definition at line 137 of file vthread.cpp.
References VString::chars(), getDeleteAtEnd(), VException::getError(), getLoggerName(), getManagementInterface(), getName(), NULL, run(), VManagementInterface::threadEnded(), threadID(), VManagementInterface::threadStarting(), and VException::what().
void VThread::getThreadsInfo | ( | VBentoNode & | bento | ) | [static] |
Returns a Bento data hierarchy describing the set of threads existent at the time of the call.
Note that upon return, some of those threads may end, and others may start; this is why we do not return thread pointers.
bento | a bento node, presumed to be empty-constructed, which will be filled out with a name, and a child for each thread |
Definition at line 207 of file vthread.cpp.
References VBentoNode::addBool(), VBentoNode::addNewChildNode(), VBentoNode::addS64(), VBentoNode::addString(), getName(), mCreateDetached, mDeleteAtEnd, mIsDeleted, mIsRunning, mManager, mThreadID, NULL, and VBentoNode::setName().
VString VThread::getThreadName | ( | VThreadID_Type | threadID | ) | [static] |
Returns the name of the VThread specified by thread id, if it exists.
If the thread does not exist, an empty string is returned.
threadID | the id of the thread to find |
Definition at line 225 of file vthread.cpp.
References VString::EMPTY(), and getName().
void VThread::stopThread | ( | VThreadID_Type | threadID | ) | [static] |
Calls stop() on a VThread specified by thread id, if it exists.
If the thread does not exists, this does nothing. If the thread does exist, stop() is called, and there are no guarantees about whether the VThread will still exist upon return, because it may terminate before return or after.
threadID | the id of the thread to stop |
Definition at line 238 of file vthread.cpp.
References stop().
void VThread::threadCreate | ( | VThreadID_Type * | threadID, |
bool | createDetached, | ||
threadMainFunction | threadMainProcPtr, | ||
void * | threadArgument | ||
) | [static] |
Starts up a new running thread.
Wrapper on Unix for pthread_create.
threadID | pointer to where to return the new thread's ID |
createDetached | true to create the thread in detached state; false if not. |
threadMainProcPtr | the thread main function that will be invoked |
threadArgument | the argument to be passed to the thread main |
VException | if the thread cannot be created |
Definition at line 25 of file vthread_platform.cpp.
void VThread::threadExit | ( | ) | [static] |
Terminates the current thread.
This could be called from anywhere, but the VThread model is to gracefully stop() the thread; so VThread::exit() is called by the thread main function at its end, and should probably not be called from anywhere else. Wrapper on Unix for pthread_exit.
Definition at line 70 of file vthread_platform.cpp.
References NULL.
bool VThread::threadJoin | ( | VThreadID_Type | threadID, |
void ** | value | ||
) | [static] |
Blocks the calling thread until the specified thread ends.
Wrapper on Unix for pthread_join.
threadID | ID of the thread to wait on |
value | pointer to storage for thread exit value |
Definition at line 75 of file vthread_platform.cpp.
void VThread::threadDetach | ( | VThreadID_Type | threadID | ) | [static] |
Marks the specified thread's storage to be reclaimed when the thread terminates.
This function does not terminate the thread. Wrapper on Unix for pthread_detach.
threadID | ID of the thread to detach |
Definition at line 80 of file vthread_platform.cpp.
VThreadID_Type VThread::threadSelf | ( | ) | [static] |
Returns the ID of the currently executing thread (the caller's thread).
Wrapper on Unix for pthread_self.
Definition at line 85 of file vthread_platform.cpp.
VThread * VThread::getCurrentThread | ( | ) | [static] |
Returns the current thread's VThread.
If the current thread is main or a thread that was not created using VThread, a dummy "stand-in" object is returned, that is not actually running or having a valid thread ID. But this means we guarantee to not return NULL.
Definition at line 189 of file vthread.cpp.
VString VThread::getCurrentThreadName | ( | ) | [static] |
This is a preferred alternative to getCurrentThread()->getName() to handle the case where it is called from a thread that was not created with a VThread.
It is smart enough to return a name converted from the thread ID, rather than using the dummy "stand-in" thread object that has a single name.
Definition at line 194 of file vthread.cpp.
References getCurrentThread(), getName(), threadSelf(), and VSTRING_S64.
bool VThread::setPriority | ( | int | nice | ) | [static] |
Sets the current thread's priority, specifying the Unix nice level.
Wrapper for Unix setpriority using PRIO_PROCESS.
nice | the nice level |
Definition at line 90 of file vthread_platform.cpp.
void VThread::sleep | ( | const VDuration & | interval | ) | [static] |
Blocks the current thread for a specified number of milliseconds.
The thread will resume execution after approximately that amount of time, although the exact runtime behavior depends on the system load.
interval | the amount of time to sleep for |
Definition at line 95 of file vthread_platform.cpp.
References VDuration::getDurationMilliseconds(), VDuration::getDurationSeconds(), and NULL.
void VThread::yield | ( | ) | [static] |
Yields to other threads.
This is a way of the calling thread being more cooperative with other threads. Unfortunately, the behavior is very different on each platform due to different facilities available.
Definition at line 105 of file vthread_platform.cpp.
References VDuration::MILLISECOND(), and sleep().
volatile bool VThread::mIsRunning [protected] |