-
class
MessageTransceiverThread
(Return to index)
-
This is a utility class to help interface multithreaded BeOScode more easily to a TCP socket that is sending and receivingPortableMessages. Only compiles under BeOS!
Type:
Include file:
../../besupport/MessageTransceiverThread.h
It helps by allowing you to send and receive
PortableMessages without having to worry about calling select(),
or any blocking issues.
Usage: 1. Create a new MessageTransceiverThread object.
2. Call StartThread(), StartAcceptThread(), StartServerThread(), or StartConnectThread().
3. Whenever you wish to send a PortableMessage over the TCP socket,
simply call SendOutgoingMessage().
4. Whenever a PortableMessage is received, a PORTABLE_MESSAGES_RECEIVED
BMessage will be sent to the BMessenger you specified in StartThread().
When you get this, you can respond by calling GetNextIncomingMessage()
on this object to retrieve the PortableMessage.
5. When you are done, just delete this object normally. If you wish,
you can call WaitForAllMessagesToBeSent() first, in order to ensure
that all pending outbound messages get delivered.
6. That's it!
Synopsis:
- Public:
- static ThreadSafeObjectPool<PortableMessage> *
GetMessagePool
()
;
-
- static ThreadSafeObjectPool<PortableMessageRef::RefCountMem> *
GetMessageRefPool
()
;
-
- status_t
GetNextIncomingConnection
(int & returnSocketFD)
;
-
- status_t
GetNextIncomingMessage
(PortableMessageRef & setRef)
;
-
- int
GetPort
() const
;
-
-
MessageTransceiverThread
(const BMessenger & replyTarget, int32 threadPri = B_NORMAL_PRIORITY)
;
-
-
MessageTransceiverThread
(int32 threadPri = B_NORMAL_PRIORITY)
;
-
- status_t
SendOutgoingMessage
(const PortableMessageRef & msgRef)
;
-
- void
SetGatewayFactoryFunc
(GatewayFactoryFunc func)
;
-
- void
SetOutgoingQueueDrainedMessage
(const BMessage * msg)
;
-
- void
SetReplyTarget
(const BMessenger & target)
;
-
- status_t
StartAcceptThread
(int port, bool acceptMultiple, const BMessage * optConnectMessage = NULL, const BMessage * optDisconnectMessage = NULL)
;
-
- status_t
StartConnectThread
(const char * hostname, int port, const BMessage * optConnectMessage = NULL, const BMessage * optDisconnectMessage = NULL)
;
-
- status_t
StartServerThread
(int port, const BMessage & connectMessage, bool acceptMultiple=true)
;
-
- status_t
StartThread
(AbstractMessageIOGateway * gateway, int datafd, const BMessage * optDisconnectMessage = NULL)
;
-
- void
WaitForAllMessagesToBeSent
()
;
-
- virtual
~MessageTransceiverThread
()
;
-
Public methods:
- public static ThreadSafeObjectPool<PortableMessage> *
GetMessagePool ()
Returns a pointer to a singleton thread-safe message pool.
Equivalent to ::GetMessagePool(), but for use in multithreaded BeOS environments.
- public static ThreadSafeObjectPool<PortableMessageRef::RefCountMem> *
GetMessageRefPool ()
Returns a pointer to a singleton thread-safe message ref pool.
Equivalent to ::GetMessageRefPool(), but for use in multithreaded BeOS environments.
- public status_t
GetNextIncomingConnection (int & returnSocketFD)
This call is only useful for MessageTransceiverThreads that are running in server mode
(i.e. that you have called StartServerThread() on). It will retrieve the next queued
incoming TCP connection socket and copy it into (returnSocketFD). If a socket is
returned to you, your code becomes the owner of the socket.
If there is no incoming connection ready, this method will return B_ERROR.
- public status_t
GetNextIncomingMessage (PortableMessageRef & setRef)
If there are any incoming messages pending, places a reference to the next one into (setRef) and returns B_NO_ERROR.
Otherwise returns B_ERROR.
- public int
GetPort () const
Returns the port number that the accept thread is accepting messages on.
This number is only meaningful if StartAcceptThread() was called.
- public
MessageTransceiverThread (const BMessenger & replyTarget, int32 threadPri = B_NORMAL_PRIORITY)
(replyTarget) specified where you want the PORTABLE_MESSAGES_RECEIVED (and other messages) sent to .
(threadPri) is the priority the TCP thread should run at.
- public
MessageTransceiverThread (int32 threadPri = B_NORMAL_PRIORITY)
Creates a receiver thread without a reply target. You should
call SetReplyTarget() before calling StartThread()...
- public status_t
SendOutgoingMessage (const PortableMessageRef & msgRef)
Enqueues (msgRef) for immediate output over the TCP connection.
Returns B_NO_ERROR on success, B_ERROR if no more messages can be sent (e.g. connection is broken)
Note that it is NOT safe to keep your own local copies of (msgRef) around
after this method returns (because PortableMessageRef isn't thread safe)
NOTE: If you want to use object pools with your (msgRef), make sure that the
pools you use are ThreadSafeObjectPools objects, or you will suffer from
nasty race conditions. The GetThreadSafeMessagePool() and GetThreadSafeMessageRefPool()
methods in this class return appropriate pool objects to use here.
- public void
SetGatewayFactoryFunc (GatewayFactoryFunc func)
- public void
SetOutgoingQueueDrainedMessage (const BMessage * msg)
Call this if you wish to receive a BMessage every time the outgoing message queue empties.
(msg) should point to the message to send, or be NULL to turn off empty-queue-messaging.
A copy of (*msg) will be made.
- public void
SetReplyTarget (const BMessenger & target)
Sets or resets the reply target for this thread
- public status_t
StartAcceptThread (int port, bool acceptMultiple, const BMessage * optConnectMessage = NULL, const BMessage * optDisconnectMessage = NULL)
Creates a TCP send/receive thread that waits for connections on the given port.
If (port) is 0, then the system will choose a port to accept on. The port number it
chooses can be discovered by calling GetPort().
(acceptMultiple), if true, will allow subsequent connections to be accepted after the first one is closed.
In no case will there be more than one connection active at a time, however.
(optConnectMessage), if specified, will be sent via your BMessenger when the connection
is complete. (A copy of this message is made).
(optDisconnectMessage), if specified, will be sent via your BMessenger when the connection
fails or is broken. (A copy of this message is made).
- public status_t
StartConnectThread (const char * hostname, int port, const BMessage * optConnectMessage = NULL, const BMessage * optDisconnectMessage = NULL)
Creates a TCP send/receive thread that connects to the given hostname and port.
(hostname) is the Internet hostname of the computer to connect to.
(port) is the port number to connect on.
(optConnectMessage), if specified, will be sent via your BMessenger when the connection
is complete. (A copy of this message is made).
(optDisconnectMessage), if specified, will be sent via your BMessenger when the connection
fails or is broken. (A copy of this message is made).
- public status_t
StartServerThread (int port, const BMessage & connectMessage, bool acceptMultiple=true)
Creates a TCP accept thread that waits for connections on the given port.
If (port) is 0, then the system will choose a port to accept on. The port number it
chooses can be discovered by calling GetPort().
The difference between calling this call and StartAcceptThread() lies in how the
incoming connection is handled. With StartAcceptThread(), the incoming connection
becomes the 'current connection' for this object, and PortableMessages are sent and
received as usual. With this method, on the other hand, an incoming connection is
accepted and placed into an incoming-connections queue, and the (connectMessage) you
specify is sent to your handler. Your handler should then call GetNextIncomingConnection()
on this object to retrieve the socket for the new connection, which can be handled with
a new MessageTransceiverThread or however you like.
If (acceptMultiple) is false, then only the first incoming connection will ever be accepted.
- public status_t
StartThread (AbstractMessageIOGateway * gateway, int datafd, const BMessage * optDisconnectMessage = NULL)
Creates and activates the TCP send/receive background thread.
(gateway) is the AbstractMessageIOGateway the thread should use to send and receive data.
In general, a AbstractMessageIOGateway object with a non-blocking TCPSocketDataIO
that uses your socket is the way to go here.
(optConnectMessage), if specified, will be sent via your BMessenger when the connection
is complete. (A copy of this message is made).
(optDisconnectMessage), if specified, will be sent via your BMessenger when the connection
fails or is broken. (A copy of this message is made).
- public void
WaitForAllMessagesToBeSent ()
Waits until all messages that were on the queue to be sent are sent, and then returns B_NO_ERROR.
If for some reason it could not wait, B_ERROR is returned.
- public virtual
~MessageTransceiverThread ()
May be called at any time