headers/bsd: Add sys/queue.h.
[haiku.git] / src / servers / app / DelayedMessage.h
blob1faf355e3473b67824367395caccc4ab8733ab91
1 /*
2 * Copyright 2015, Haiku.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Joseph Groover <looncraz@looncraz.net>
7 */
8 #ifndef AS_DELAYED_MESSAGE_H
9 #define AS_DELAYED_MESSAGE_H
12 #include <ObjectList.h>
13 #include <OS.h>
16 //! Method by which to merge DelayedMessages with the same code.
17 enum DMMergeMode {
18 DM_NO_MERGE = 0, // Will send this message, and the other(s)
19 DM_MERGE_REPLACE = 1, // Replace older data with newer data
20 DM_MERGE_CANCEL = 2, // keeps older data, cancels this message
21 DM_MERGE_DUPLICATES = 3 // If data is the same, cancel new message
25 //! Merge-mode data-matching, set which data must match to merge messages.
26 enum {
27 DM_DATA_DEFAULT = 0, // Match all for DUPLICATES & none for REPLACE modes.
28 DM_DATA_1 = 1 << 0,
29 DM_DATA_2 = 1 << 1,
30 DM_DATA_3 = 1 << 2,
31 DM_DATA_4 = 1 << 3,
32 DM_DATA_5 = 1 << 4,
33 DM_DATA_6 = 1 << 5
37 //! Convenient delay definitions.
38 enum {
39 DM_MINIMUM_DELAY = 500ULL,
40 DM_SHORT_DELAY = 1000ULL,
41 DM_120HZ_DELAY = 8888ULL,
42 DM_60HZ_DELAY = 16666ULL,
43 DM_MEDIUM_DELAY = 15000ULL,
44 DM_30HZ_DELAY = 33332ULL,
45 DM_15HZ_DELAY = 66664ULL,
46 DM_LONG_DELAY = 100000ULL,
47 DM_QUARTER_SECOND_DELAY = 250000ULL,
48 DM_HALF_SECOND_DELAY = 500000ULL,
49 DM_ONE_SECOND_DELAY = 1000000ULL,
50 DM_ONE_MINUTE_DELAY = DM_ONE_SECOND_DELAY * 60,
51 DM_ONE_HOUR_DELAY = DM_ONE_MINUTE_DELAY * 60
55 class DelayedMessageData;
58 /*! \class DelayedMessage
59 \brief Friendly API for creating messages to be sent at a future time.
61 Messages can be sent with a relative delay, or at a set time. Messages with
62 the same code can be merged according to various rules. Each message can
63 have any number of target recipients.
65 DelayedMessage is a throw-away object, it is to be created on the stack,
66 Flush()'d, then left to be destructed when out of scope.
68 class DelayedMessage {
69 typedef void(*FailureCallback)(int32 code, port_id port, void* data);
70 public:
71 DelayedMessage(int32 code, bigtime_t delay,
72 bool isSpecificTime = false);
74 ~DelayedMessage();
76 // At least one target port is required.
77 bool AddTarget(port_id port);
79 // Merge messages with the same code according to the following
80 // rules and data matching mask.
81 void SetMerge(DMMergeMode mode, uint32 match = 0);
83 // Called for each port on which the message was failed to be sent.
84 void SetFailureCallback(FailureCallback callback,
85 void* data = NULL);
87 template <class Type>
88 status_t Attach(const Type& data);
89 status_t Attach(const void* data, size_t size);
91 template <class Type>
92 status_t AttachList(const BObjectList<Type>& list);
94 template <class Type>
95 status_t AttachList(const BObjectList<Type>& list,
96 bool* whichArray);
98 status_t Flush();
100 // Private
101 DelayedMessageData* HandOff();
102 DelayedMessageData* Data() {return fData;}
104 private:
105 // Forbidden methods - these are one time-use objects.
106 void* operator new(size_t);
107 void* operator new[](size_t);
109 DelayedMessageData* fData;
110 bool fHandedOff;
114 // #pragma mark Implementation
117 template <class Type>
118 status_t
119 DelayedMessage::Attach(const Type& data)
121 return Attach(&data, sizeof(Type));
125 template <class Type>
126 status_t
127 DelayedMessage::AttachList(const BObjectList<Type>& list)
129 if (list.CountItems() == 0)
130 return B_BAD_VALUE;
132 status_t error = Attach<int32>(list.CountItems());
134 for (int32 index = 0; index < list.CountItems(); ++index) {
135 if (error != B_OK)
136 break;
138 error = Attach<Type>(*(list.ItemAt(index)));
141 return error;
145 template <class Type>
146 status_t
147 DelayedMessage::AttachList(const BObjectList<Type>& list, bool* which)
149 if (list.CountItems() == 0)
150 return B_BAD_VALUE;
152 if (which == NULL)
153 return AttachList(list);
155 int32 count = 0;
156 for (int32 index = 0; index < list.CountItems(); ++index) {
157 if (which[index])
158 ++count;
161 if (count == 0)
162 return B_BAD_VALUE;
164 status_t error = Attach<int32>(count);
166 for (int32 index = 0; index < list.CountItems(); ++index) {
167 if (error != B_OK)
168 break;
170 if (which[index])
171 error = Attach<Type>(*list.ItemAt(index));
174 return error;
178 #endif // AS_DELAYED_MESSAGE_H