#include <Thread.h>
Inheritance diagram for Thread:

Public Types | |
| enum | { SOCKET_SET_READ = 0, SOCKET_SET_WRITE, SOCKET_SET_EXCEPTION, NUM_SOCKET_SETS } |
| Enumeration of the socket sets that are available for blocking on; used in GetOwnerSocketSet() and GetInternalSocketSet() calls. More... | |
Public Member Functions | |
| Thread () | |
| Constructor. | |
| virtual | ~Thread () |
| Destructor. | |
| virtual status_t | StartInternalThread () |
| Start the internal thread running. | |
| bool | IsInternalThreadRunning () const |
| Returns true iff the thread is considered to be running. | |
| bool | IsCallerInternalThread () const |
| Returns true iff the calling thread is the internal thread, or false if the caller is any other thread. | |
| virtual void | ShutdownInternalThread (bool waitForThread=true) |
| Tells the internal thread to quit by sending it a NULL MessageRef, and then optionally waits for it to go away by calling WaitForInternalThreadToExit(). | |
| status_t | WaitForInternalThreadToExit () |
| Blocks and won't return until after the internal thread exits. | |
| virtual status_t | SendMessageToInternalThread (const MessageRef &msg) |
| Puts the given message into a message queue for the internal thread to pick up, and then calls SignalInternalThread() (if necessary) to signal the internal thread that a new message is ready. | |
| virtual int32 | GetNextReplyFromInternalThread (MessageRef &ref, uint64 wakeupTime=0) |
| This method attempts to retrieve the next reply message that has been sent back to the main thread by the internal thread (via SendMessageToOwner()). | |
| Queue< MessageRef > * | LockAndReturnMessageQueue () |
| Locks the internal thread's message queue and returns a pointer to it. | |
| status_t | UnlockMessageQueue () |
| Unlocks our internal message queue, so that the internal thread can again pop messages off of it. | |
| Queue< MessageRef > * | LockAndReturnReplyQueue () |
| Locks this Thread's reply queue and returns a pointer to it. | |
| status_t | UnlockReplyQueue () |
| Unlocks the reply message queue, so that the internal thread can again append messages to it. | |
| const SocketRef & | GetOwnerWakeupSocket () |
| Returns the socket that the main thread may select() for read on for wakeup-notification bytes. | |
| Hashtable< SocketRef, bool > & | GetOwnerSocketSet (uint32 socketSet) |
| This function returns a reference to one of the three socket-sets that GetNextReplyFromInternalThread() will optionally use to determine whether to return early. | |
|
const Hashtable< SocketRef, bool > & | GetOwnerSocketSet (uint32 socketSet) const |
| As above, but returns a read-only reference. | |
Protected Member Functions | |
| virtual status_t | MessageReceivedFromOwner (const MessageRef &msgRef, uint32 numLeft) |
| If you are using the default implementation of InternalThreadEntry(), then this method will be called whenever a new MessageRef is received by the internal thread. | |
| status_t | SendMessageToOwner (const MessageRef &replyRef) |
| May be called by the internal thread to send a Message back to the owning thread. | |
| virtual void | InternalThreadEntry () |
| You may override this method to be your Thread's execution entry point. | |
| virtual int32 | WaitForNextMessageFromOwner (MessageRef &ref, uint64 wakeupTime=MUSCLE_TIME_NEVER) |
| This method is meant to be called by the internally held thread. | |
| virtual void | SignalInternalThread () |
| Called by SendMessageToThread() whenever there is a need to wake up the internal thread so that it will look at its reply queue. | |
| virtual void | SignalOwner () |
| Called by SendMessageToOwner() whenever there is a need to wake up the owning thread so that it will look at its reply queue. | |
| const SocketRef & | GetInternalThreadWakeupSocket () |
| Returns the socket that the internal thread may select() for read on for wakeup-notification bytes. | |
| status_t | LockSignalling () |
| Locks the lock we use to serialize calls to SignalInternalThread() and SignalOwner(). | |
| status_t | UnlockSignalling () |
| Unlocks the lock we use to serialize calls to SignalInternalThread() and SignalOwner(). | |
| void | CloseSockets () |
| Closes all of our threading sockets, if they are open. | |
| Hashtable< SocketRef, bool > & | GetInternalSocketSet (uint32 socketSet) |
| This function returns a reference to one of the three socket-sets that WaitForNextMessageFromOwner() will optionally use to determine whether to return early. | |
|
const Hashtable< SocketRef, bool > & | GetInternalSocketSet (uint32 socketSet) const |
| As above, but returns a read-only reference. | |
Classes | |
| class | ThreadSpecificData |
| This class encapsulates data that is used by one of our two threads (internal or owner). | |
You will want to subclass Thread in order to specify the behaviour of the internally held thread... The default thread implementation doesn't do anything very useful. It also includes support for sending Messages to the thread, receiving reply Messages from the thread, and for waiting for the thread to exit.
Definition at line 43 of file Thread.h.
| anonymous enum |
Enumeration of the socket sets that are available for blocking on; used in GetOwnerSocketSet() and GetInternalSocketSet() calls.
| Thread::Thread | ( | ) |
Constructor.
Does very little (in particular, the internal thread is not started here... that happens when you call StartInternalThread())
| virtual Thread::~Thread | ( | ) | [virtual] |
Destructor.
You must have made sure that the internal thread is no longer running before deleting the Thread object, or an assertion failure will occur. (You should make sure the internal thread is gone by calling WaitForInternalThreadToExit() before deleting this Thread object)
| virtual status_t Thread::StartInternalThread | ( | ) | [virtual] |
Start the internal thread running.
Reimplemented in AcceptSocketsThread, and MessageTransceiverThread.
| bool Thread::IsInternalThreadRunning | ( | ) | const [inline] |
Returns true iff the thread is considered to be running.
(Note that the thread is considered running from the time StartInternalThread() returns B_NO_ERROR until the time WaitForInternalThreadToExit() is called and returns B_NO_ERROR. Even if the thread terminates itself before then, it is still considered to be 'running' as far as we're concerned)
| virtual void Thread::ShutdownInternalThread | ( | bool | waitForThread = true |
) | [virtual] |
Tells the internal thread to quit by sending it a NULL MessageRef, and then optionally waits for it to go away by calling WaitForInternalThreadToExit().
If the internal thread isn't running, this method is a no-op. You must call this before deleting the MessageTransceiverThread object!
| waitForThread | if true, this method won't return until the thread is gone. Defaults to true. (if you set this to false, you'll need to also call WaitForThreadToExit() before deleting this object) |
| status_t Thread::WaitForInternalThreadToExit | ( | ) |
Blocks and won't return until after the internal thread exits.
If you have called StartInternalThread(), you'll need to call this method (or ShutdownInternalThread()) before deleting this Thread object or calling StartInternalThread() again--even if your thread has already terminated itself! That way consistency is guaranteed and race conditions are avoided.
| virtual status_t Thread::SendMessageToInternalThread | ( | const MessageRef & | msg | ) | [virtual] |
Puts the given message into a message queue for the internal thread to pick up, and then calls SignalInternalThread() (if necessary) to signal the internal thread that a new message is ready.
If the internal thread isn't currently running, then the MessageRef will be queued up and available to the internal thread to process when it is started.
| msg | Reference to the message that is to be given to the internal thread. |
| virtual int32 Thread::GetNextReplyFromInternalThread | ( | MessageRef & | ref, | |
| uint64 | wakeupTime = 0 | |||
| ) | [virtual] |
This method attempts to retrieve the next reply message that has been sent back to the main thread by the internal thread (via SendMessageToOwner()).
| ref | On success, (ref) will be a reference to the new reply message. | |
| wakeupTime | Time at which this method should stop blocking and return, even if there is no new reply message ready. If this value is 0 (the default) or otherwise less than the current time (as returned by GetRunTime64()), then this method does a non-blocking poll of the reply queue. If (wakeuptime) is set to MUSCLE_TIME_NEVER, then this method will block indefinitely, until a new reply is ready. |
| Queue<MessageRef>* Thread::LockAndReturnMessageQueue | ( | ) |
Locks the internal thread's message queue and returns a pointer to it.
Since the queue is locked, you may examine or modify the queue safely. Once this method has returned successfully, you are responsible for unlocking the message queue again by calling UnlockMessageQueue(). If you don't, the Thread will remain locked and stuck!
| status_t Thread::UnlockMessageQueue | ( | ) |
Unlocks our internal message queue, so that the internal thread can again pop messages off of it.
Should be called exactly once after each successful call to LockAndReturnMessageQueue(). After this call returns, it is no longer safe to use the pointer that was previously returned by LockAndReturnMessageQueue().
| Queue<MessageRef>* Thread::LockAndReturnReplyQueue | ( | ) |
Locks this Thread's reply queue and returns a pointer to it.
Since the queue is locked, you may examine or modify the queue safely. Once this method has returned successfully, you are responsible for unlocking the message queue again by calling UnlockReplyQueue(). If you don't, the Thread will remain locked and stuck!
| status_t Thread::UnlockReplyQueue | ( | ) |
Unlocks the reply message queue, so that the internal thread can again append messages to it.
Should be called exactly once after each successful call to LockAndReturnReplyQueue(). After this call returns, it is no longer safe to use the pointer that was previously returned by LockAndReturnReplyQueue().
| const SocketRef& Thread::GetOwnerWakeupSocket | ( | ) |
Returns the socket that the main thread may select() for read on for wakeup-notification bytes.
This Thread object's thread-signalling sockets will be allocated by this method if they aren't already allocated.
This function returns a reference to one of the three socket-sets that GetNextReplyFromInternalThread() will optionally use to determine whether to return early.
By default, all of the socket-sets are empty, and GetNextReplyFromInternalThread() will return only when a new Message has arrived from the internal thread, or when the timeout period has elapsed.
However, in some cases it is useful to have GetNextReplyFromInternalThread() return under other conditions as well, such as when a specified socket becomes ready-to-read-from or ready-to-write-to. You can specify that a socket should be watched in this manner, by adding that socket to the appropriate socket set(s). For example, to tell GetNextReplyFromInternalThread() to always return when mySocket is ready to be written to, you would add mySocket to the SOCKET_SET_WRITE set, like this:
_thread.GetOwnerSocketSet(SOCKET_SET_WRITE).Put(mySocket, false);
(This only needs to be done once) After GetNextReplyFromInternalThread() returns, you can determine whether your socket is ready-to-write-to by checking its associated value in the table, like this:
bool canWrite = false; _thread.GetOwnerSocketSet(SOCKET_SET_WRITE).Get(mySocket, canWrite); if (canWrite) printf("Socket is ready to be written to!\n");
| socketSet | SOCKET_SET_* indicating which socket-set to return a reference to. |
| virtual status_t Thread::MessageReceivedFromOwner | ( | const MessageRef & | msgRef, | |
| uint32 | numLeft | |||
| ) | [protected, virtual] |
If you are using the default implementation of InternalThreadEntry(), then this method will be called whenever a new MessageRef is received by the internal thread.
Default implementation does nothing, and returns B_NO_ERROR if (msgRef) is valid, or B_ERROR if (msgRef) is a NULL reference.
| msgRef | Reference to the just-received Message object. | |
| numLeft | Number of Messages still left in the owner's message queue. |
| status_t Thread::SendMessageToOwner | ( | const MessageRef & | replyRef | ) | [protected] |
May be called by the internal thread to send a Message back to the owning thread.
Puts the given MessageRef into the replies queue, and then calls SignalOwner() (if necessary) to notify the main thread that replies are pending.
| replyRef | MessageRef to send back to the owning thread. |
| virtual void Thread::InternalThreadEntry | ( | ) | [protected, virtual] |
You may override this method to be your Thread's execution entry point.
Default implementation runs in a loop calling WaitForNextMessageFromOwner() and then MessageReceivedFromOwner(). In many cases, that is all you need, so you may not need to override this method.
Reimplemented in AcceptSocketsThread, and MessageTransceiverThread.
| virtual int32 Thread::WaitForNextMessageFromOwner | ( | MessageRef & | ref, | |
| uint64 | wakeupTime = MUSCLE_TIME_NEVER | |||
| ) | [protected, virtual] |
This method is meant to be called by the internally held thread.
It will attempt retrieve the next message that has been sent to the thread via SendMessageToThread().
| ref | On success, (ref) will be set to be a reference to the retrieved Message. | |
| wakeupTime | Time at which this method should stop blocking and return, even if there is no new message ready. If this value is 0 or otherwise less than the current time (as returned by GetRunTime64()), then this method does a non-blocking poll of the queue. If (wakeuptime) is set to MUSCLE_TIME_NEVER (the default value), then this method will block indefinitely, until a Message is ready. |
| virtual void Thread::SignalInternalThread | ( | ) | [protected, virtual] |
Called by SendMessageToThread() whenever there is a need to wake up the internal thread so that it will look at its reply queue.
Default implementation sends a byte on a socket to implement this, but you can override this method to do it a different way if you need to.
| virtual void Thread::SignalOwner | ( | ) | [protected, virtual] |
Called by SendMessageToOwner() whenever there is a need to wake up the owning thread so that it will look at its reply queue.
Default implementation sends a byte to the main-thread-listen socket, but you can override this method to do it different way if you need to.
Reimplemented in muscle::QAcceptSocketsThread, muscle::QMessageTransceiverThread, SDLMessageTransceiverThread, and Win32MessageTransceiverThread.
| const SocketRef& Thread::GetInternalThreadWakeupSocket | ( | ) | [protected] |
Returns the socket that the internal thread may select() for read on for wakeup-notification bytes.
This Thread object's thread-signalling sockets will be allocated by this method if they aren't already allocated.
| status_t Thread::LockSignalling | ( | ) | [inline, protected] |
Locks the lock we use to serialize calls to SignalInternalThread() and SignalOwner().
Be sure to call UnlockSignallingLock() when you are done with the lock.
Definition at line 264 of file Thread.h.
References Mutex::Lock().
| status_t Thread::UnlockSignalling | ( | ) | [inline, protected] |
Unlocks the lock we use to serialize calls to SignalInternalThread() and SignalOwner().
Definition at line 269 of file Thread.h.
References Mutex::Unlock().
This function returns a reference to one of the three socket-sets that WaitForNextMessageFromOwner() will optionally use to determine whether to return early.
By default, all of the socket-sets are empty, and WaitForNextMessageFromOwner() will return only when a new Message has arrived from the owner thread, or when the timeout period has elapsed.
However, in some cases it is useful to have WaitForNextMessageFromOwner() return under other conditions as well, such as when a specified socket becomes ready-to-read-from or ready-to-write-to. You can specify that a socket should be watched in this manner, by adding that socket to the appropriate socket set(s). For example, to tell WaitForNextMessageFromOwner() to always return when mySocket is ready to be written to, you would add mySocket to the SOCKET_SET_WRITE set, like this:
_thread.GetInternalSocketSet(SOCKET_SET_WRITE).Put(mySocket, false);
(This only needs to be done once) After WaitForNextMessageFromOwner() returns, you can determine whether your socket is ready-to-write-to by checking its associated value in the table, like this:
bool canWrite = false; _thread.GetInternalSocketSet(SOCKET_SET_WRITE).Get(mySocket, canWrite); if (canWrite) printf("Socket is ready to be written to!\n");
| socketSet | SOCKET_SET_* indicating which socket-set to return a reference to. |
1.5.1