1 /*
2 
3   					W3C Sample Code Library libwww Event Class
4 
5 
6 !
7   The Event Class
8 !
9 */
10 
11 /*
12 **	(c) COPYRIGHT MIT 1995.
13 **	Please first read the full copyright statement in the file COPYRIGH.
14 */
15 
16 /*
17 
18 The Event Class defines any event manager to be used by libwww for handling
19 events. An event is not strictly defined as it is highly platform
20 dependent and hence out of scope for the Library. If you are using the libwww
21 pseudo threads on Unix then an event is when the select() system
22 call returns a notification on a socket descriptor, but it may as well
23 be an asynchronous event from the windows manager etc. If your application
24 is not using anything but traditional blocking sockets then you do not need
25 an event manager at all. In that case, libwww will block on any socket or
26 system call until the process can proceed.
27 
28 The libwww interface to an event manager is very simple as it consists of
29 registering a socket descriptor, the location in the
30 program, and the current state when an operation (for example
31 read) would block. When the event manager at a later point in
32 time gets a notification that the socket has become ready, it can then call
33 libwww with the state saved from the registration and libwww can continue.
34 Second, libwww must be able to unregister a socket when it is not
35 anymore in a state where it can block. Only in case the application
36 wishes to use non-blocking sockets it should register methods for
37 handling the registration process as described below.
38 
39 Note: The library core does not define any event manager
40 - it is considered part of the application. The library comes with a
41 default event manager which can be initiated
42 using the function HTEventInit() in HTInit
43 module
44 
45 This module is implemented by HTEvent.c, and it is
46 a part of the W3C Sample Code Library.
47 */
48 
49 #ifndef HTEVENT_H
50 #define HTEVENT_H
51 #include "wwwsys.h"
52 
53 #ifdef __cplusplus
54 extern "C" {
55 #endif
56 
57 #ifdef IN_EVENT
58 typedef struct _HTTimer HTTimer;
59 #endif
60 
61 typedef enum _HTPriority {
62     HT_PRIORITY_INV = -1,
63     HT_PRIORITY_OFF = 0,
64     HT_PRIORITY_MIN = 1,
65     HT_PRIORITY_MAX = 20
66 } HTPriority;
67 
68 #define HTEVENT_INDEX 0x10
69 typedef enum {
70 #ifdef WWW_WIN_ASYNC
71     HTEvent_READ    = (0x001 | 0 << HTEVENT_INDEX),
72     HTEvent_WRITE   = (0x002 | 1 << HTEVENT_INDEX),
73     HTEvent_OOB     = (0x004 | 2 << HTEVENT_INDEX),
74     HTEvent_ACCEPT  = (0x008 | 3 << HTEVENT_INDEX),
75     HTEvent_CONNECT = (0x010 | 4 << HTEVENT_INDEX),
76     HTEvent_CLOSE   = (0x020 | 5 << HTEVENT_INDEX),
77     HTEvent_TYPES   = 6,	/* winsock has seperate events for all of these */
78 #define HTEVENT_TYPES	6 /* use in constructing the fake event below */
79 #else /* WWW_WIN_ASYNC */
80     HTEvent_READ    = (0x001 | 0 << HTEVENT_INDEX),
81     HTEvent_ACCEPT  = (0x002 | 0 << HTEVENT_INDEX),
82     HTEvent_CLOSE   = (0x004 | 0 << HTEVENT_INDEX),
83     HTEvent_WRITE   = (0x008 | 1 << HTEVENT_INDEX),
84     HTEvent_CONNECT = (0x010 | 1 << HTEVENT_INDEX),
85     HTEvent_OOB     = (0x020 | 2 << HTEVENT_INDEX),
86     HTEvent_TYPES   = 3,	/* only READ, WRITE, and OOB are real types */
87 #define HTEVENT_TYPES	3 /* use in constructing the fake event below */
88 #endif /* !WWW_WIN_ASYNC */
89     /*
90     **	fake events - these don't correspond to event manager events, but they
91     **	are usefull for communicating with the protocol modules
92     */
93     HTEvent_TIMEOUT = (0x040 | HTEVENT_TYPES << HTEVENT_INDEX),
94     HTEvent_BEGIN   = (0x000 | HTEVENT_TYPES << HTEVENT_INDEX),
95     HTEvent_END     = (0x080 | HTEVENT_TYPES << HTEVENT_INDEX),
96     HTEvent_FLUSH   = (0x100 | HTEVENT_TYPES << HTEVENT_INDEX),
97     HTEvent_RESET   = (0x200 | HTEVENT_TYPES << HTEVENT_INDEX),
98     HTEvent_ALL     = 0xFFFF
99 } HTEventType;
100 
101 #define HTEvent_BITS(type) (type & 0xFFFF)
102 #define HTEvent_INDEX(type) (type >> HTEVENT_INDEX)
103 
104 #define HT_EVENT_INITIALIZER \
105     {HTEvent_READ, "HTEvent_READ"}, \
106     {HTEvent_ACCEPT, "HTEvent_ACCEPT"}, \
107     {HTEvent_CLOSE, "HTEvent_CLOSE"}, \
108     {HTEvent_WRITE, "HTEvent_WRITE"}, \
109     {HTEvent_CONNECT, "HTEvent_CONNECT"}, \
110     {HTEvent_OOB, "HTEvent_OOB"}, \
111     {HTEvent_TIMEOUT, "HTEvent_TIMEOUT"}, \
112     {HTEvent_BEGIN, "HTEvent_BEGIN"}, \
113     {HTEvent_END, "HTEvent_END"}, \
114     {HTEvent_FLUSH, "HTEvent_FLUSH"}, \
115     {HTEvent_RESET, "HTEvent_RESET"}
116 
117 extern char * HTEvent_type2str(HTEventType type);
118 
119 /*
120 .
121   Event Handlers
122 .
123 
124 A location is a function that can be registered by the event manager
125 and called at a later point in time in order to continue an operation. All
126 locations must be of type &nbsp;HTEventCallback as defined here:
127 */
128 
129 typedef int HTEventCallback (SOCKET, void *, HTEventType);
130 typedef struct _HTEvent HTEvent;
131 
132 /* Avoid circular include for HTReq->HTNet->HTHost: HTEvent blah */
133 #include "HTReq.h"
134 
135 /*
136 
137 There are many default event handlers provided with the Library. For example,
138 all the protocol modules such as the HTTP client module
139 are implemented as event handlers. In stead of using blocking sockets, this
140 allows a protocol module to register itself when performing an operation
141 that would block. When the sockets becomes ready the handler is called with
142 th socket in question, the request object, and the socket operation &nbsp;
143 .
144   Registering and Unregistering Events
145 .
146 
147 As mentioned above, the only interface libwww requires from an event manager
148 is a method to register an event when an operation would block and
149 unregister it when the operation has completed The library registers
150 and unregisters events by calling the following two functions:
151 */
152 
153 extern int HTEvent_register	(SOCKET, HTEventType, HTEvent *);
154 extern int HTEvent_unregister	(SOCKET, HTEventType);
155 
156 /*
157 
158 The register function contains information about which socket we are waiting
159 on to get ready and which operation we are waiting for (read, write, etc.),
160 the request object containing the current request, the event handler that
161 we want to be called when the socket becomes reasy, and finally the priority
162 by which we want the thread to be processed by the event manager. Likewise,
163 libwww can unregister a operation on a socket which means that libwww is
164 no longer waiting for this actiion to become ready.
165 .
166   Registering an Event Manager
167 .
168 
169 Libwww core does not contain any event manager as it depends on whether you
170 want to use pseudo threads no threads, or real threads. Instead, libwww comes
171 with a default implementation that you may register,
172 but you may as well implement and register your own. The register and unregister
173 functions above actually does nothing than looking for a registered event
174 manager and then passes the call on to that. You register your own event
175 manager by using the methods below:
176 */
177 
178 typedef int HTEvent_registerCallback(SOCKET, HTEventType, HTEvent *);
179 typedef int HTEvent_unregisterCallback(SOCKET, HTEventType);
180 
181 extern void HTEvent_setRegisterCallback(HTEvent_registerCallback *);
182 extern void HTEvent_setUnregisterCallback(HTEvent_unregisterCallback *);
183 
184 /*
185 (
186   Has Register and Unregister Callbacks been setup?
187 )
188 
189 Replies YES if both an HTEvent_setRegisterCallback and
190 HTEvent_setUnregisterCallback have been called with non NULL callbacks.
191 */
192 
193 extern BOOL HTEvent_isCallbacksRegistered(void);
194 
195 /*
196 .
197   Create and Delete Events
198 .
199 */
200 
201 extern HTEvent * HTEvent_new (HTEventCallback * cbf, void * context,
202 			      HTPriority pritority, int timeoutInMillis);
203 extern BOOL HTEvent_delete (HTEvent * event);
204 
205 /*
206 (
207   Event Timeouts, Priorities, Callbacks, and Contexts
208 )
209 
210 Normally, these are set when creating the event.
211 */
212 
213 extern BOOL HTEvent_setParam(HTEvent * event, void * param);
214 extern BOOL HTEvent_setPriority(HTEvent * event, HTPriority priority);
215 extern BOOL HTEvent_setTimeout(HTEvent * event, int timeoutInMillis);
216 extern BOOL HTEvent_setCallback(HTEvent * event, HTEventCallback * cbf);
217 
218 /*
219 .
220   The Raw Event Type
221 .
222 
223 Don't use this directly, use the methods above instead.
224 */
225 
226 struct _HTEvent {
227     HTPriority		priority;	 /* Priority of this request (event) */
228     int                 millis;              /* Timeout in ms for this event */
229 #ifdef IN_EVENT
230     HTTimer *		timer;
231 #endif
232     HTEventCallback *	cbf;			   /* Protocol state machine */
233     void *		param;		       /* HTEvent_register parameter */
234     HTRequest *		request;
235 };
236 
237 /*
238 
239 You can register the event manager provided together with libwww by using
240 the HTEventInit() in the HTInit module
241 */
242 
243 #ifdef __cplusplus
244 }
245 #endif
246 
247 #endif /* HTEVENT_H */
248 
249 /*
250 
251 
252 
253   @(#) $Id$
254 
255 */
256