Commit 83e47afa267040a24ed363972ef709f99a92f5e3
1 parent
5da874ff
Exists in
master
and in
3 other branches
Updating event dispatcher, starting to split windows and linux code.
Showing
5 changed files
with
435 additions
and
278 deletions
Show diff stats
lib3270.cbp
... | ... | @@ -157,6 +157,9 @@ |
157 | 157 | <Unit filename="src/lib3270/kybd.c"> |
158 | 158 | <Option compilerVar="CC" /> |
159 | 159 | </Unit> |
160 | + <Unit filename="src/lib3270/linux/event_dispatcher.c"> | |
161 | + <Option compilerVar="CC" /> | |
162 | + </Unit> | |
160 | 163 | <Unit filename="src/lib3270/log.c"> |
161 | 164 | <Option compilerVar="CC" /> |
162 | 165 | </Unit> |
... | ... | @@ -209,9 +212,6 @@ |
209 | 212 | <Unit filename="src/lib3270/sf.c"> |
210 | 213 | <Option compilerVar="CC" /> |
211 | 214 | </Unit> |
212 | - <Unit filename="src/lib3270/ssl.c"> | |
213 | - <Option compilerVar="CC" /> | |
214 | - </Unit> | |
215 | 215 | <Unit filename="src/lib3270/ssl/init.c"> |
216 | 216 | <Option compilerVar="CC" /> |
217 | 217 | </Unit> |
... | ... | @@ -245,6 +245,9 @@ |
245 | 245 | <Unit filename="src/lib3270/version.c"> |
246 | 246 | <Option compilerVar="CC" /> |
247 | 247 | </Unit> |
248 | + <Unit filename="src/lib3270/windows/event_dispatcher.c"> | |
249 | + <Option compilerVar="CC" /> | |
250 | + </Unit> | |
248 | 251 | <Unit filename="src/lib3270/windows/resources.rc" /> |
249 | 252 | <Unit filename="src/lib3270/windows/resources.rc.in" /> |
250 | 253 | <Extensions> | ... | ... |
src/lib3270/iocalls.c
... | ... | @@ -37,10 +37,10 @@ |
37 | 37 | #include "utilc.h" |
38 | 38 | |
39 | 39 | #define MILLION 1000000L |
40 | - | |
41 | -#if defined(_WIN32) | |
42 | - #define MAX_HA 256 | |
43 | -#endif | |
40 | +// | |
41 | +//#if defined(_WIN32) | |
42 | +// #define MAX_HA 256 | |
43 | +//#endif | |
44 | 44 | |
45 | 45 | /*---[ Standard calls ]-------------------------------------------------------------------------------------*/ |
46 | 46 | |
... | ... | @@ -199,6 +199,7 @@ static void * internal_add_poll(H3270 *session, int fd, LIB3270_IO_FLAG flag, vo |
199 | 199 | input_t *ip = (input_t *) lib3270_malloc(sizeof(input_t)); |
200 | 200 | |
201 | 201 | ip->session = session; |
202 | + ip->enabled = 1; | |
202 | 203 | ip->fd = fd; |
203 | 204 | ip->flag = flag; |
204 | 205 | ip->userdata = userdata; |
... | ... | @@ -285,276 +286,6 @@ LIB3270_EXPORT void * lib3270_add_poll_fd(H3270 *session, int fd, LIB3270_IO_FL |
285 | 286 | return add_poll(session,fd,flag,call,userdata); |
286 | 287 | } |
287 | 288 | |
288 | -/* Event dispatcher. */ | |
289 | -int lib3270_default_event_dispatcher(H3270 *hSession, int block) | |
290 | -{ | |
291 | -#if defined(_WIN32) | |
292 | - unsigned long long now; | |
293 | -// int i; | |
294 | - int maxSock; | |
295 | - DWORD tmo; | |
296 | -#else | |
297 | - int ns; | |
298 | - struct timeval now, twait, *tp; | |
299 | - int events; | |
300 | -#endif | |
301 | - | |
302 | - fd_set rfds, wfds, xfds; | |
303 | - | |
304 | - input_t *ip; | |
305 | - int processed_any = 0; | |
306 | - | |
307 | -retry: | |
308 | - | |
309 | - hSession->inputs_changed = 0; | |
310 | - | |
311 | - // If we've processed any input, then don't block again. | |
312 | - if(processed_any) | |
313 | - block = 0; | |
314 | - | |
315 | -#if defined(_WIN32) | |
316 | - | |
317 | - maxSock = 0; | |
318 | - | |
319 | - FD_ZERO(&rfds); | |
320 | - FD_ZERO(&wfds); | |
321 | - FD_ZERO(&xfds); | |
322 | - | |
323 | - for (ip = hSession->inputs; ip != (input_t *)NULL; ip = ip->next) | |
324 | - { | |
325 | - if(ip->flag & LIB3270_IO_FLAG_READ) | |
326 | - { | |
327 | - FD_SET(ip->fd, &rfds); | |
328 | - maxSock = max(ip->fd,maxSock); | |
329 | - } | |
330 | - | |
331 | - if(ip->flag & LIB3270_IO_FLAG_WRITE) | |
332 | - { | |
333 | - FD_SET(ip->fd, &wfds); | |
334 | - maxSock = max(ip->fd,maxSock); | |
335 | - } | |
336 | - | |
337 | - if(ip->flag & LIB3270_IO_FLAG_EXCEPTION) | |
338 | - { | |
339 | - FD_SET(ip->fd, &xfds); | |
340 | - maxSock = max(ip->fd,maxSock); | |
341 | - } | |
342 | - } | |
343 | - | |
344 | - if (block) | |
345 | - { | |
346 | - if (hSession->timeouts != TN) | |
347 | - { | |
348 | - ms_ts(&now); | |
349 | - if (now > hSession->timeouts->ts) | |
350 | - tmo = 0; | |
351 | - else | |
352 | - tmo = hSession->timeouts->ts - now; | |
353 | - } | |
354 | - else | |
355 | - { | |
356 | - // Block for 1 second (at maximal) | |
357 | - tmo = 1000; | |
358 | - } | |
359 | - } | |
360 | - else | |
361 | - { | |
362 | - tmo = 1000; | |
363 | - } | |
364 | - | |
365 | - if(maxSock) | |
366 | - { | |
367 | - struct timeval tm; | |
368 | - | |
369 | - tm.tv_sec = 0; | |
370 | - tm.tv_usec = tmo; | |
371 | - | |
372 | - int ns = select(maxSock+1, &rfds, &wfds, &xfds, &tm); | |
373 | - | |
374 | - if (ns < 0 && errno != EINTR) | |
375 | - { | |
376 | - lib3270_popup_dialog( hSession, | |
377 | - LIB3270_NOTIFY_ERROR, | |
378 | - _( "Network error" ), | |
379 | - _( "Select() failed when processing for events." ), | |
380 | - lib3270_win32_strerror(WSAGetLastError())); | |
381 | - } | |
382 | - else | |
383 | - { | |
384 | - for (ip = hSession->inputs; ip != (input_t *) NULL; ip = ip->next) | |
385 | - { | |
386 | - if((ip->flag & LIB3270_IO_FLAG_READ) && FD_ISSET(ip->fd, &rfds)) | |
387 | - { | |
388 | - (*ip->call)(ip->session,ip->fd,LIB3270_IO_FLAG_READ,ip->userdata); | |
389 | - processed_any = True; | |
390 | - if (hSession->inputs_changed) | |
391 | - goto retry; | |
392 | - } | |
393 | - | |
394 | - if ((ip->flag & LIB3270_IO_FLAG_WRITE) && FD_ISSET(ip->fd, &wfds)) | |
395 | - { | |
396 | - (*ip->call)(ip->session,ip->fd,LIB3270_IO_FLAG_WRITE,ip->userdata); | |
397 | - processed_any = True; | |
398 | - if (hSession->inputs_changed) | |
399 | - goto retry; | |
400 | - } | |
401 | - | |
402 | - if ((ip->flag & LIB3270_IO_FLAG_EXCEPTION) && FD_ISSET(ip->fd, &xfds)) | |
403 | - { | |
404 | - (*ip->call)(ip->session,ip->fd,LIB3270_IO_FLAG_EXCEPTION,ip->userdata); | |
405 | - processed_any = True; | |
406 | - if (hSession->inputs_changed) | |
407 | - goto retry; | |
408 | - } | |
409 | - } | |
410 | - } | |
411 | - } | |
412 | - else if(block) | |
413 | - { | |
414 | - Sleep(tmo); | |
415 | - } | |
416 | - | |
417 | - | |
418 | -#else | |
419 | - | |
420 | - events = 0; | |
421 | - | |
422 | - FD_ZERO(&rfds); | |
423 | - FD_ZERO(&wfds); | |
424 | - FD_ZERO(&xfds); | |
425 | - | |
426 | - for (ip = hSession->inputs; ip != (input_t *)NULL; ip = ip->next) | |
427 | - { | |
428 | - if(ip->flag & LIB3270_IO_FLAG_READ) | |
429 | - { | |
430 | - FD_SET(ip->fd, &rfds); | |
431 | - events++; | |
432 | - } | |
433 | - | |
434 | - if(ip->flag & LIB3270_IO_FLAG_WRITE) | |
435 | - { | |
436 | - FD_SET(ip->fd, &wfds); | |
437 | - events++; | |
438 | - } | |
439 | - | |
440 | - if(ip->flag & LIB3270_IO_FLAG_EXCEPTION) | |
441 | - { | |
442 | - FD_SET(ip->fd, &xfds); | |
443 | - events++; | |
444 | - } | |
445 | - } | |
446 | - | |
447 | - if (block) | |
448 | - { | |
449 | - if (hSession->timeouts != TN) | |
450 | - { | |
451 | - (void) gettimeofday(&now, (void *)NULL); | |
452 | - twait.tv_sec = hSession->timeouts->tv.tv_sec - now.tv_sec; | |
453 | - twait.tv_usec = hSession->timeouts->tv.tv_usec - now.tv_usec; | |
454 | - if (twait.tv_usec < 0L) { | |
455 | - twait.tv_sec--; | |
456 | - twait.tv_usec += MILLION; | |
457 | - } | |
458 | - if (twait.tv_sec < 0L) | |
459 | - twait.tv_sec = twait.tv_usec = 0L; | |
460 | - tp = &twait; | |
461 | - } | |
462 | - else | |
463 | - { | |
464 | - twait.tv_sec = 1; | |
465 | - twait.tv_usec = 0L; | |
466 | - tp = &twait; | |
467 | - } | |
468 | - } | |
469 | - else | |
470 | - { | |
471 | - twait.tv_sec = 1; | |
472 | - twait.tv_usec = 0L; | |
473 | - tp = &twait; | |
474 | - | |
475 | - if(!events) | |
476 | - return processed_any; | |
477 | - } | |
478 | - | |
479 | - ns = select(FD_SETSIZE, &rfds, &wfds, &xfds, tp); | |
480 | - | |
481 | - if (ns < 0 && errno != EINTR) | |
482 | - { | |
483 | - lib3270_popup_dialog( hSession, | |
484 | - LIB3270_NOTIFY_ERROR, | |
485 | - _( "Network error" ), | |
486 | - _( "Select() failed when processing for events." ), | |
487 | - "%s", | |
488 | - strerror(errno)); | |
489 | - } | |
490 | - else | |
491 | - { | |
492 | - for (ip = hSession->inputs; ip != (input_t *) NULL; ip = ip->next) | |
493 | - { | |
494 | - if((ip->flag & LIB3270_IO_FLAG_READ) && FD_ISSET(ip->fd, &rfds)) | |
495 | - { | |
496 | - (*ip->call)(ip->session,ip->fd,LIB3270_IO_FLAG_READ,ip->userdata); | |
497 | - processed_any = True; | |
498 | - if (hSession->inputs_changed) | |
499 | - goto retry; | |
500 | - } | |
501 | - | |
502 | - if((ip->flag & LIB3270_IO_FLAG_WRITE) && FD_ISSET(ip->fd, &wfds)) | |
503 | - { | |
504 | - (*ip->call)(ip->session,ip->fd,LIB3270_IO_FLAG_WRITE,ip->userdata); | |
505 | - processed_any = True; | |
506 | - if (hSession->inputs_changed) | |
507 | - goto retry; | |
508 | - } | |
509 | - | |
510 | - if((ip->flag & LIB3270_IO_FLAG_EXCEPTION) && FD_ISSET(ip->fd, &xfds)) | |
511 | - { | |
512 | - (*ip->call)(ip->session,ip->fd,LIB3270_IO_FLAG_EXCEPTION,ip->userdata); | |
513 | - processed_any = True; | |
514 | - if (hSession->inputs_changed) | |
515 | - goto retry; | |
516 | - } | |
517 | - } | |
518 | - } | |
519 | - | |
520 | -#endif | |
521 | - | |
522 | - // See what's expired. | |
523 | - if (hSession->timeouts != TN) | |
524 | - { | |
525 | -#if defined(_WIN32) | |
526 | - struct timeout *t; | |
527 | - ms_ts(&now); | |
528 | -#else | |
529 | - struct timeout *t; | |
530 | - (void) gettimeofday(&now, (void *)NULL); | |
531 | -#endif | |
532 | - | |
533 | - while ((t = hSession->timeouts) != TN) | |
534 | - { | |
535 | -#if defined(_WIN32) | |
536 | - if (t->ts <= now) | |
537 | -#else | |
538 | - if (t->tv.tv_sec < now.tv_sec ||(t->tv.tv_sec == now.tv_sec && t->tv.tv_usec < now.tv_usec)) | |
539 | -#endif | |
540 | - { | |
541 | - hSession->timeouts = t->next; | |
542 | - t->in_play = True; | |
543 | - (*t->proc)(t->session); | |
544 | - processed_any = True; | |
545 | - lib3270_free(t); | |
546 | - } else | |
547 | - break; | |
548 | - } | |
549 | - } | |
550 | - | |
551 | - if (hSession->inputs_changed) | |
552 | - goto retry; | |
553 | - | |
554 | - return processed_any; | |
555 | - | |
556 | -} | |
557 | - | |
558 | 289 | static int internal_wait(H3270 *hSession, int seconds) |
559 | 290 | { |
560 | 291 | time_t end = time(0) + seconds; | ... | ... |
... | ... | @@ -0,0 +1,204 @@ |
1 | +/* | |
2 | + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 | |
3 | + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a | |
4 | + * aplicativos mainframe. Registro no INPI sob o nome G3270. | |
5 | + * | |
6 | + * Copyright (C) <2008> <Banco do Brasil S.A.> | |
7 | + * | |
8 | + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob | |
9 | + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela | |
10 | + * Free Software Foundation. | |
11 | + * | |
12 | + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER | |
13 | + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO | |
14 | + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para | |
15 | + * obter mais detalhes. | |
16 | + * | |
17 | + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este | |
18 | + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin | |
19 | + * St, Fifth Floor, Boston, MA 02110-1301 USA | |
20 | + * | |
21 | + * Este programa está nomeado como - e possui - linhas de código. | |
22 | + * | |
23 | + * Contatos: | |
24 | + * | |
25 | + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) | |
26 | + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) | |
27 | + * | |
28 | + */ | |
29 | + | |
30 | + /** | |
31 | + * @brief Implements the default event dispatcher for linux. | |
32 | + * | |
33 | + */ | |
34 | + | |
35 | +#include "../private.h" | |
36 | +#include <sys/time.h> | |
37 | +#include <sys/types.h> | |
38 | +// #include "../xioc.h" | |
39 | +// #include "telnetc.h" | |
40 | +// #include "utilc.h" | |
41 | + | |
42 | +#define MILLION 1000000L | |
43 | +#define TN (timeout_t *)NULL | |
44 | + | |
45 | +/*---[ Implement ]------------------------------------------------------------------------------------------*/ | |
46 | + | |
47 | +/** | |
48 | + * @brief lib3270's default event dispatcher. | |
49 | + * | |
50 | + * @param hSession TN3270 session to process. | |
51 | + * @param block If non zero, the method blocks waiting for event. | |
52 | + * | |
53 | + */ | |
54 | +int lib3270_default_event_dispatcher(H3270 *hSession, int block) | |
55 | +{ | |
56 | + int ns; | |
57 | + struct timeval now, twait, *tp; | |
58 | + int events; | |
59 | + | |
60 | + fd_set rfds, wfds, xfds; | |
61 | + | |
62 | + input_t *ip; | |
63 | + int processed_any = 0; | |
64 | + | |
65 | +retry: | |
66 | + | |
67 | + hSession->inputs_changed = 0; | |
68 | + | |
69 | + // If we've processed any input, then don't block again. | |
70 | + if(processed_any) | |
71 | + block = 0; | |
72 | + | |
73 | + events = 0; | |
74 | + | |
75 | + FD_ZERO(&rfds); | |
76 | + FD_ZERO(&wfds); | |
77 | + FD_ZERO(&xfds); | |
78 | + | |
79 | + for (ip = hSession->inputs; ip != (input_t *)NULL; ip = (input_t *) ip->next) | |
80 | + { | |
81 | + if(!ip->enabled) | |
82 | + { | |
83 | + debug("Socket %d is disabled",ip->fd); | |
84 | + continue; | |
85 | + } | |
86 | + | |
87 | + if(ip->flag & LIB3270_IO_FLAG_READ) | |
88 | + { | |
89 | + FD_SET(ip->fd, &rfds); | |
90 | + events++; | |
91 | + } | |
92 | + | |
93 | + if(ip->flag & LIB3270_IO_FLAG_WRITE) | |
94 | + { | |
95 | + FD_SET(ip->fd, &wfds); | |
96 | + events++; | |
97 | + } | |
98 | + | |
99 | + if(ip->flag & LIB3270_IO_FLAG_EXCEPTION) | |
100 | + { | |
101 | + FD_SET(ip->fd, &xfds); | |
102 | + events++; | |
103 | + } | |
104 | + } | |
105 | + | |
106 | + if (block) | |
107 | + { | |
108 | + if (hSession->timeouts != TN) | |
109 | + { | |
110 | + (void) gettimeofday(&now, (void *)NULL); | |
111 | + twait.tv_sec = hSession->timeouts->tv.tv_sec - now.tv_sec; | |
112 | + twait.tv_usec = hSession->timeouts->tv.tv_usec - now.tv_usec; | |
113 | + if (twait.tv_usec < 0L) { | |
114 | + twait.tv_sec--; | |
115 | + twait.tv_usec += MILLION; | |
116 | + } | |
117 | + if (twait.tv_sec < 0L) | |
118 | + twait.tv_sec = twait.tv_usec = 0L; | |
119 | + tp = &twait; | |
120 | + } | |
121 | + else | |
122 | + { | |
123 | + twait.tv_sec = 1; | |
124 | + twait.tv_usec = 0L; | |
125 | + tp = &twait; | |
126 | + } | |
127 | + } | |
128 | + else | |
129 | + { | |
130 | + twait.tv_sec = 1; | |
131 | + twait.tv_usec = 0L; | |
132 | + tp = &twait; | |
133 | + | |
134 | + if(!events) | |
135 | + return processed_any; | |
136 | + } | |
137 | + | |
138 | + ns = select(FD_SETSIZE, &rfds, &wfds, &xfds, tp); | |
139 | + | |
140 | + if (ns < 0 && errno != EINTR) | |
141 | + { | |
142 | + lib3270_popup_dialog( hSession, | |
143 | + LIB3270_NOTIFY_ERROR, | |
144 | + _( "Network error" ), | |
145 | + _( "Select() failed when processing for events." ), | |
146 | + "%s", | |
147 | + strerror(errno)); | |
148 | + } | |
149 | + else | |
150 | + { | |
151 | + for (ip = hSession->inputs; ip != (input_t *) NULL; ip = (input_t *) ip->next) | |
152 | + { | |
153 | + if((ip->flag & LIB3270_IO_FLAG_READ) && FD_ISSET(ip->fd, &rfds)) | |
154 | + { | |
155 | + (*ip->call)(ip->session,ip->fd,LIB3270_IO_FLAG_READ,ip->userdata); | |
156 | + processed_any = True; | |
157 | + if (hSession->inputs_changed) | |
158 | + goto retry; | |
159 | + } | |
160 | + | |
161 | + if((ip->flag & LIB3270_IO_FLAG_WRITE) && FD_ISSET(ip->fd, &wfds)) | |
162 | + { | |
163 | + (*ip->call)(ip->session,ip->fd,LIB3270_IO_FLAG_WRITE,ip->userdata); | |
164 | + processed_any = True; | |
165 | + if (hSession->inputs_changed) | |
166 | + goto retry; | |
167 | + } | |
168 | + | |
169 | + if((ip->flag & LIB3270_IO_FLAG_EXCEPTION) && FD_ISSET(ip->fd, &xfds)) | |
170 | + { | |
171 | + (*ip->call)(ip->session,ip->fd,LIB3270_IO_FLAG_EXCEPTION,ip->userdata); | |
172 | + processed_any = True; | |
173 | + if (hSession->inputs_changed) | |
174 | + goto retry; | |
175 | + } | |
176 | + } | |
177 | + } | |
178 | + | |
179 | + // See what's expired. | |
180 | + if (hSession->timeouts != TN) | |
181 | + { | |
182 | + struct timeout *t; | |
183 | + (void) gettimeofday(&now, (void *)NULL); | |
184 | + | |
185 | + while ((t = hSession->timeouts) != TN) | |
186 | + { | |
187 | + if (t->tv.tv_sec < now.tv_sec ||(t->tv.tv_sec == now.tv_sec && t->tv.tv_usec < now.tv_usec)) | |
188 | + { | |
189 | + hSession->timeouts = t->next; | |
190 | + t->in_play = True; | |
191 | + (*t->proc)(t->session); | |
192 | + processed_any = True; | |
193 | + lib3270_free(t); | |
194 | + } else | |
195 | + break; | |
196 | + } | |
197 | + } | |
198 | + | |
199 | + if (hSession->inputs_changed) | |
200 | + goto retry; | |
201 | + | |
202 | + return processed_any; | |
203 | + | |
204 | +} | ... | ... |
src/lib3270/private.h
... | ... | @@ -0,0 +1,218 @@ |
1 | +/* | |
2 | + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 | |
3 | + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a | |
4 | + * aplicativos mainframe. Registro no INPI sob o nome G3270. | |
5 | + * | |
6 | + * Copyright (C) <2008> <Banco do Brasil S.A.> | |
7 | + * | |
8 | + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob | |
9 | + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela | |
10 | + * Free Software Foundation. | |
11 | + * | |
12 | + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER | |
13 | + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO | |
14 | + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para | |
15 | + * obter mais detalhes. | |
16 | + * | |
17 | + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este | |
18 | + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin | |
19 | + * St, Fifth Floor, Boston, MA 02110-1301 USA | |
20 | + * | |
21 | + * Este programa está nomeado como - e possui - linhas de código. | |
22 | + * | |
23 | + * Contatos: | |
24 | + * | |
25 | + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) | |
26 | + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) | |
27 | + * | |
28 | + */ | |
29 | + | |
30 | + /** | |
31 | + * @brief Implements the default event dispatcher for windows. | |
32 | + * | |
33 | + */ | |
34 | + | |
35 | +#include "../private.h" | |
36 | +#include <sys/time.h> | |
37 | +#include <sys/types.h> | |
38 | +//#include "xioc.h" | |
39 | +//#include "telnetc.h" | |
40 | +//#include "utilc.h" | |
41 | + | |
42 | +//#define MILLION 1000000L | |
43 | +// #define MAX_HA 256 | |
44 | +//#endif | |
45 | + | |
46 | +/*---[ Implement ]------------------------------------------------------------------------------------------*/ | |
47 | + | |
48 | +static void ms_ts(unsigned long long *u) | |
49 | +{ | |
50 | + FILETIME t; | |
51 | + | |
52 | + /* Get the system time, in 100ns units. */ | |
53 | + GetSystemTimeAsFileTime(&t); | |
54 | + memcpy(u, &t, sizeof(unsigned long long)); | |
55 | + | |
56 | + /* Divide by 10,000 to get ms. */ | |
57 | + *u /= 10000ULL; | |
58 | +} | |
59 | + | |
60 | +/** | |
61 | + * @brief lib3270's default event dispatcher. | |
62 | + * | |
63 | + * @param hSession TN3270 session to process. | |
64 | + * @param block If non zero, the method blocks waiting for event. | |
65 | + * | |
66 | + */ | |
67 | +int lib3270_default_event_dispatcher(H3270 *hSession, int block) | |
68 | +{ | |
69 | + unsigned long long now; | |
70 | + int maxSock; | |
71 | + DWORD tmo; | |
72 | + | |
73 | + fd_set rfds, wfds, xfds; | |
74 | + | |
75 | + input_t *ip; | |
76 | + int processed_any = 0; | |
77 | + | |
78 | +retry: | |
79 | + | |
80 | + hSession->inputs_changed = 0; | |
81 | + | |
82 | + // If we've processed any input, then don't block again. | |
83 | + if(processed_any) | |
84 | + block = 0; | |
85 | + | |
86 | + maxSock = 0; | |
87 | + | |
88 | + FD_ZERO(&rfds); | |
89 | + FD_ZERO(&wfds); | |
90 | + FD_ZERO(&xfds); | |
91 | + | |
92 | + for (ip = hSession->inputs; ip != (input_t *)NULL; ip = ip->next) | |
93 | + { | |
94 | + if(!ip->enabled) | |
95 | + { | |
96 | + debug("Socket %d is disabled",ip->fd); | |
97 | + continue; | |
98 | + } | |
99 | + | |
100 | + if(ip->flag & LIB3270_IO_FLAG_READ) | |
101 | + { | |
102 | + FD_SET(ip->fd, &rfds); | |
103 | + maxSock = max(ip->fd,maxSock); | |
104 | + } | |
105 | + | |
106 | + if(ip->flag & LIB3270_IO_FLAG_WRITE) | |
107 | + { | |
108 | + FD_SET(ip->fd, &wfds); | |
109 | + maxSock = max(ip->fd,maxSock); | |
110 | + } | |
111 | + | |
112 | + if(ip->flag & LIB3270_IO_FLAG_EXCEPTION) | |
113 | + { | |
114 | + FD_SET(ip->fd, &xfds); | |
115 | + maxSock = max(ip->fd,maxSock); | |
116 | + } | |
117 | + } | |
118 | + | |
119 | + if (block) | |
120 | + { | |
121 | + if (hSession->timeouts != TN) | |
122 | + { | |
123 | + ms_ts(&now); | |
124 | + if (now > hSession->timeouts->ts) | |
125 | + tmo = 0; | |
126 | + else | |
127 | + tmo = hSession->timeouts->ts - now; | |
128 | + } | |
129 | + else | |
130 | + { | |
131 | + // Block for 1 second (at maximal) | |
132 | + tmo = 1000; | |
133 | + } | |
134 | + } | |
135 | + else | |
136 | + { | |
137 | + tmo = 1000; | |
138 | + } | |
139 | + | |
140 | + if(maxSock) | |
141 | + { | |
142 | + struct timeval tm; | |
143 | + | |
144 | + tm.tv_sec = 0; | |
145 | + tm.tv_usec = tmo; | |
146 | + | |
147 | + int ns = select(maxSock+1, &rfds, &wfds, &xfds, &tm); | |
148 | + | |
149 | + if (ns < 0 && errno != EINTR) | |
150 | + { | |
151 | + lib3270_popup_dialog( hSession, | |
152 | + LIB3270_NOTIFY_ERROR, | |
153 | + _( "Network error" ), | |
154 | + _( "Select() failed when processing for events." ), | |
155 | + lib3270_win32_strerror(WSAGetLastError())); | |
156 | + } | |
157 | + else | |
158 | + { | |
159 | + for (ip = hSession->inputs; ip != (input_t *) NULL; ip = ip->next) | |
160 | + { | |
161 | + if((ip->flag & LIB3270_IO_FLAG_READ) && FD_ISSET(ip->fd, &rfds)) | |
162 | + { | |
163 | + (*ip->call)(ip->session,ip->fd,LIB3270_IO_FLAG_READ,ip->userdata); | |
164 | + processed_any = True; | |
165 | + if (hSession->inputs_changed) | |
166 | + goto retry; | |
167 | + } | |
168 | + | |
169 | + if ((ip->flag & LIB3270_IO_FLAG_WRITE) && FD_ISSET(ip->fd, &wfds)) | |
170 | + { | |
171 | + (*ip->call)(ip->session,ip->fd,LIB3270_IO_FLAG_WRITE,ip->userdata); | |
172 | + processed_any = True; | |
173 | + if (hSession->inputs_changed) | |
174 | + goto retry; | |
175 | + } | |
176 | + | |
177 | + if ((ip->flag & LIB3270_IO_FLAG_EXCEPTION) && FD_ISSET(ip->fd, &xfds)) | |
178 | + { | |
179 | + (*ip->call)(ip->session,ip->fd,LIB3270_IO_FLAG_EXCEPTION,ip->userdata); | |
180 | + processed_any = True; | |
181 | + if (hSession->inputs_changed) | |
182 | + goto retry; | |
183 | + } | |
184 | + } | |
185 | + } | |
186 | + } | |
187 | + else if(block) | |
188 | + { | |
189 | + Sleep(tmo); | |
190 | + } | |
191 | + | |
192 | + // See what's expired. | |
193 | + if (hSession->timeouts != TN) | |
194 | + { | |
195 | + struct timeout *t; | |
196 | + ms_ts(&now); | |
197 | + | |
198 | + while ((t = hSession->timeouts) != TN) | |
199 | + { | |
200 | + if (t->ts <= now) | |
201 | + { | |
202 | + hSession->timeouts = t->next; | |
203 | + t->in_play = True; | |
204 | + (*t->proc)(t->session); | |
205 | + processed_any = True; | |
206 | + lib3270_free(t); | |
207 | + } else | |
208 | + break; | |
209 | + } | |
210 | + } | |
211 | + | |
212 | + if (hSession->inputs_changed) | |
213 | + goto retry; | |
214 | + | |
215 | + return processed_any; | |
216 | + | |
217 | +} | |
218 | + | ... | ... |