1/*
2 * Copyright 2005, Ingo Weinhold, bonefish@users.sf.net. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5
6#ifndef MESSAGE_DELIVERER_H
7#define MESSAGE_DELIVERER_H
8
9#include <Locker.h>
10#include <Messenger.h>
11
12struct messaging_target;
13
14// MessagingTargetSet
15class MessagingTargetSet {
16public:
17	virtual ~MessagingTargetSet();
18
19	virtual bool HasNext() const = 0;
20	virtual bool Next(port_id &port, int32 &token) = 0;
21	virtual void Rewind() = 0;
22};
23
24// DefaultMessagingTargetSet
25class DefaultMessagingTargetSet : public MessagingTargetSet {
26public:
27	DefaultMessagingTargetSet(const messaging_target *targets,
28		int32 targetCount);
29	virtual ~DefaultMessagingTargetSet();
30
31	virtual bool HasNext() const;
32	virtual bool Next(port_id &port, int32 &token);
33	virtual void Rewind();
34
35private:
36	const messaging_target	*fTargets;
37	int32					fTargetCount;
38	int32					fNextIndex;
39};
40
41// SingleMessagingTargetSet
42class SingleMessagingTargetSet : public MessagingTargetSet {
43public:
44	SingleMessagingTargetSet(BMessenger target);
45	SingleMessagingTargetSet(port_id port, int32 token);
46	virtual ~SingleMessagingTargetSet();
47
48	virtual bool HasNext() const;
49	virtual bool Next(port_id &port, int32 &token);
50	virtual void Rewind();
51
52private:
53	port_id				fPort;
54	int32				fToken;
55	bool				fAtBeginning;
56};
57
58// MessageDeliverer
59class MessageDeliverer {
60private:
61	MessageDeliverer();
62	~MessageDeliverer();
63
64	status_t Init();
65
66public:
67	static status_t CreateDefault();
68	static void DeleteDefault();
69	static MessageDeliverer *Default();
70
71	status_t DeliverMessage(BMessage *message, BMessenger target,
72		bigtime_t timeout = B_INFINITE_TIMEOUT);
73	status_t DeliverMessage(BMessage *message, MessagingTargetSet &targets,
74		bigtime_t timeout = B_INFINITE_TIMEOUT);
75	status_t DeliverMessage(const void *message, int32 messageSize,
76		MessagingTargetSet &targets, bigtime_t timeout = B_INFINITE_TIMEOUT);
77
78private:
79	class Message;
80	class TargetMessage;
81	class TargetMessageHandle;
82	class TargetPort;
83	struct TargetPortMap;
84
85	TargetPort *_GetTargetPort(port_id portID, bool create = false);
86	void _PutTargetPort(TargetPort *port);
87
88	status_t _SendMessage(Message *message, port_id portID, int32 token);
89
90	static int32 _DelivererThreadEntry(void *data);
91	int32 _DelivererThread();
92
93	static MessageDeliverer	*sDeliverer;
94
95	BLocker			fLock;
96	TargetPortMap	*fTargetPorts;
97	thread_id		fDelivererThread;
98	volatile bool	fTerminating;
99};
100
101#endif	// MESSAGE_DELIVERER_H
102