EventSvc.h
1/* -*- C++ -*-
2 * Copyright (c) 2005-2010, Isode Limited, London, England.
3 * All rights reserved.
4 *
5 * Acquisition and use of this software and related materials for any
6 * purpose requires a written licence agreement from Isode Limited,
7 * or a written licence from an organisation licenced by Isode Limited
8 * to grant such a licence.
9 */
10
11/*
12 *
13 * \file EventSvc.h
14 *
15 * \brief Interface for core Event service framework.
16 *
17 * @VERSION@
18 */
19
20#ifndef _EVENTSVC_H_
21#define _EVENTSVC_H_
22
23#include "cdecl.h"
24#include <isode/base/messages.h>
25
26#ifdef __cplusplus
27
28namespace Event {
29 class Manager;
30 class Receiver;
31 class AsyncEventRef;
32
34 //
36
37 class AsyncEvent {
38 private:
40 // Note: this is maintained by the AsyncEventRef under the
41 // control of the main event service
42 AsyncEventRef *_queued;
43
44 Receiver *_rcvr;
45
46 // This is a friend class, as it sets the _queued value
47 friend class AsyncEventRef;
48
49 protected:
51 inline void SetReceiver (Receiver *rcvr) { _rcvr = rcvr; }
52
53 public:
55 AsyncEvent () : _queued (0), _rcvr (0) { }
56
58 virtual ~AsyncEvent () { if ( _queued ) Cancel(); }
59
61 inline AsyncEventRef *Reference () const { return _queued; }
62
64 Receiver *GetReceiver () const { return _rcvr; }
65
67 virtual void Deliver() = 0;
68
70 virtual bool ShouldDelete () const { return false; }
71
73 inline void Cancel ();
74 };
75
77 // This is used when the manager should queue the event to this receiver
78 // So that the event is on a queue until delivery is serialized for the
79 // receiver object.
80 class Receiver {
81 public:
83 virtual ~Receiver() {}
84
86 virtual void Queue (AsyncEvent *event) = 0;
87
89 virtual void Extract (AsyncEvent *event) = 0;
90
92 virtual void Process() = 0;
93
94 };
95
98
99 class AsyncEventRef {
100 private:
102 AsyncEvent *_event;
103
104 // This is a friend class, as it can call Extract()
105 friend class Manager;
106
108 virtual void extract() = 0;
109
110 protected:
112 AsyncEventRef(AsyncEvent *event) : _event(event) {
113 event->_queued = this;
114 }
115
116 AsyncEventRef() : _event(0) {}
117
118 virtual ~AsyncEventRef() {}
119
120 void Set (AsyncEvent *event) {
121 _event = event;
122 event->_queued = this;
123 }
124
125 public:
126 inline AsyncEvent *Extract () {
127 AsyncEvent *ep = _event;
128
129 ep->_queued = 0;
130
131 extract();
132
133 return ep;
134 }
135 };
136
138 //
141
142 class Manager {
143 private:
144 static EVENTSVC_DLL Manager *_instance;
145
146 public:
148 virtual ~Manager() {}
149
151 static inline Manager *GetManager() {
152 return _instance;
153 }
154
156 virtual bool IsThreaded () = 0;
157
159 virtual void Dequeue (AsyncEvent *event) = 0;
160
169 virtual void Run (bool isthread) = 0;
170
172 // Returns true if there are significant events queued,
173 // so that it can be called again to deliver them.
174 virtual bool Poll (
175 const timespec *when,
176 bool immediate,
177 pthread_mutex_t *mutex,
178 pthread_cond_t *cond) = 0;
179
181 virtual void Terminate(
182 unsigned int millisecs
183 ) = 0;
184
186 virtual void Blocking() = 0;
187
189 virtual void Unblocked() = 0;
190
192 static inline void about2Block() {
193 if ( _instance ) _instance->Blocking();
194 }
195
197 static inline void nowUnblocked() {
198 if ( _instance ) _instance->Unblocked();
199 }
200
203 virtual bool LongLived() = 0;
204
206 // (Cannot be Yield() as this fails on Windows)
207 static inline bool Yielding() {
208 if ( _instance ) return _instance->LongLived();
209
210 return false;
211 }
212
214 virtual void SetThreads (
215 int activethreads,
216 int maxthreads
217 ) = 0;
218
220 virtual int GetActiveLimit () = 0;
221
222 static const int MAXPRIO = 100;
223
227 virtual void Queue (
228 AsyncEvent *event,
229 unsigned priority = 0,
230 bool nostart = false
231 ) = 0;
232
234 virtual void QueueAt (
235 AsyncEvent *event,
236 const struct timespec *abstime
237 ) = 0;
238
240 virtual void QueueAt (
241 AsyncEvent *event,
242 unsigned millisec
243 ) = 0;
244
246 virtual void QueueAtExit (AsyncEvent *event) = 0;
247
249 virtual const struct timespec *NextEventDue () = 0;
250
252 //
254 static int ManagerFactory (
255 const char *type,
256 MSGstruct *msg
257 );
258 };
259
260 inline void AsyncEvent::Cancel () {
261 // Note: must call the Dequeue routine
262 // Whether the event is queued or not needs to be under the
263 // control of the main manager mutex.
264 Manager::GetManager()->Dequeue (this);
265 }
266
268
271
272 template<class U, class D> class AsyncEventAux : public AsyncEvent {
273 private:
274 U *_user;
275 D _data;
276
277 public:
279 AsyncEventAux () : _user(0) {}
280
282 void SetUser (U *u) { _user = u; }
283
285 void SetUserData (U *u, D &d) { _user = u; _data = d; }
286
288 virtual void Deliver () {
289 _user->Deliver (&_data);
290 }
291
293 virtual void Deliver (D *dp) {
294 _user->Deliver (dp);
295 }
296
298 void Send (Manager *mgr, D *dp) {
299 _data = *dp;
300
301 mgr->Queue (this, 0);
302 }
303 };
304
305}
306#endif /* __cplusplus */
307
310IC_CDECL EVENTSVC_DLL int EventServiceInit (
311 const char *managertype,
312 const char *pollertype,
313 MSGstruct *msp
314);
315
316/* Manager types */
317
318#define EVENTSVC_THREADMANAGER "thread"
319#define EVENTSVC_POLLMANAGER "poll"
320
322IC_CDECL EVENTSVC_DLL void EventServiceRun (void);
323
325IC_CDECL EVENTSVC_DLL void EventServiceLongLived (void);
326
328IC_CDECL EVENTSVC_DLL void EventServiceTerminate (
329 int millisecs
330);
331
332
333#endif /* _EVENTSVC_H_ */

All rights reserved © 2002 - 2024 Isode Ltd.