/* * Modification History * * 2003-July-20 Jason Rohrer * Created. * * 2003-August-25 Jason Rohrer * Added support for registering message handler functions. * * 2003-October-7 Jason Rohrer * Added separate locks for handlers and receive addresses to fix deadlocks. * * 2003-December-5 Jason Rohrer * Added support for message utility. */ #ifndef LOCAL_ADDRESS_RECEIVER_INCLUDED #define LOCAL_ADDRESS_RECEIVER_INCLUDED #include "minorGems/network/p2pParts/OutboundChannel.h" #include "minorGems/util/SimpleVector.h" #include "minorGems/system/MutexLock.h" /** * Class that is used interally to encapsulate information about registered * handler functions. * * @author Jason Rohrer. */ class MessageHandlerWrapper { public: int mHandlerID; int (*mHandlerFunction)( char *, char *, char *, void * ); void *mExtraHandlerArgument; }; /** * A class that queues messages received on local virtual addresses. * * All calls are thread-safe. * * @author Jason Rohrer. */ class LocalAddressReceiver { public: /** * Constructs a receiver. */ LocalAddressReceiver(); ~LocalAddressReceiver(); /** * Adds an address that this node will receive on. * * @param inAddress a virtual address to receive messages on. * Must be destroyed by caller. */ void addReceiveAddress( char *inAddress ); /** * Removes a receive address, causing this node to stop receiving ] * on the address. * * @param inAddress a virtual address to stop receiving on. * Must be destroyed by caller. */ void removeReceiveAddress( char *inAddress ); /** * Passes a received message into this receiver. * * @param inFromAddress the virtual address that the message is from. * Must be destroyed by caller. * @param inToAddress the virtual address that the message is to. * Must be destroyed by caller. * @param inBody the body of the message. * Must be destroyed by caller. * @param outUtilityGenerated pointer to location where generated * utility should be returned. * Must be destroyed by caller. * * @return true if this message matches one of this node's * virtual addresses. */ char messageReceived( char *inFromAddress, char *inToAddress, char *inBody, int *outUtilityGenerated ); /** * Registers a handler function to process all locally-received * messages. * * Thread-safe. * * All (char *) parameters passed in to handler will be destroyed by * caller and therefore should not be destroyed by the handler. * * The extra (void *) argument can be used to encapsulate any * additional state that should be associated with a particular * handler. For example, it could be a pointer to a C++ object that * is "unwrapped" by casting inside the handler function. * * @param inHandlerFunction a pointer to the handler function. * This function must return the utility generated by the handle * and take the following arguments: * (char *inFromAddress, char *inToAddress, char *inBody, * void *inExtraArgument ). * @param inExtraHandlerArgument pointer to an extra argument to be * passed in to the handler function each time it is called. * Must be destroyed by caller after the handler is removed. * * @return an ID for this handler that can be used to remove it later. */ int addMessageHandler( int (*inHandlerFunction)( char *, char *, char *, void * ), void *inExtraHandlerArgument ); /** * Removes a message handler so that it will no longer process * locally-received messages. * * Thread-safe. * * @param inHandlerID the ID of the handler as returned by * a call to muteAddMessageHandler. */ void removeMessageHandler( int inHandlerID ); /** * Gets the number of received messages that are waiting. * * Note that this function is only useful if no message handlers are * registered. If handlers are registered, they will process all * messages and this function will always return 0. * * @param inAddress the virtual address to check for waiting messages. * Must be destroyed by caller. * * @return the number of received messages. */ unsigned int getWaitingMessageCount( char *inAddress ); /** * Gets received messages. * * Note that this function is only useful if no message handlers are * registered. If handlers are registered, they will process all * messages and this function will always return 0 messages and empty * arrays. * * @param inAddress the virtual address to get waiting messages for. * Must be destroyed by caller. * @param inNumMessages the number of messages to get. * @param outMessages pointer to location where an array of * messages should be returned. * Returned array and messages must be destroyed by caller. * @param outFromAddresses pointer to location where an array of * from addresses, one per message should be returned. * Returned array and addresses must be destroyed by caller. * * @return the number of messages being returned (may be less * than inNumMessages if fewer messages are available). */ unsigned int getReceivedMessages( char *inAddress, unsigned int inNumMessages, char ***outMessages, char ***outFromAddresses ); protected: // separate locks needed here so that a handler can // call an add/remove address function without deadlocking MutexLock *mHandlerLock; MutexLock *mReceiveAddressLock; SimpleVector *mAddressVector; int mNextFreeHandlerID; SimpleVector *mMessageHandlerVector; SimpleVector< SimpleVector* > *mMessageQueueVector; SimpleVector< SimpleVector* > *mFromAddressQueueVector; /** * Finds the index of an address in our vectors. * * Not thread-safe. * * * @param inAddress the virtual address to find the index of. * Must be destroyed by caller. * * @return the index, or -1 if the address is not found. */ int findAddressIndex( char *inAddress ); }; #endif