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 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 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