Commit 83e47afa267040a24ed363972ef709f99a92f5e3

Authored by Perry Werneck
1 parent 5da874ff

Updating event dispatcher, starting to split windows and linux code.

@@ -157,6 +157,9 @@ @@ -157,6 +157,9 @@
157 <Unit filename="src/lib3270/kybd.c"> 157 <Unit filename="src/lib3270/kybd.c">
158 <Option compilerVar="CC" /> 158 <Option compilerVar="CC" />
159 </Unit> 159 </Unit>
  160 + <Unit filename="src/lib3270/linux/event_dispatcher.c">
  161 + <Option compilerVar="CC" />
  162 + </Unit>
160 <Unit filename="src/lib3270/log.c"> 163 <Unit filename="src/lib3270/log.c">
161 <Option compilerVar="CC" /> 164 <Option compilerVar="CC" />
162 </Unit> 165 </Unit>
@@ -209,9 +212,6 @@ @@ -209,9 +212,6 @@
209 <Unit filename="src/lib3270/sf.c"> 212 <Unit filename="src/lib3270/sf.c">
210 <Option compilerVar="CC" /> 213 <Option compilerVar="CC" />
211 </Unit> 214 </Unit>
212 - <Unit filename="src/lib3270/ssl.c">  
213 - <Option compilerVar="CC" />  
214 - </Unit>  
215 <Unit filename="src/lib3270/ssl/init.c"> 215 <Unit filename="src/lib3270/ssl/init.c">
216 <Option compilerVar="CC" /> 216 <Option compilerVar="CC" />
217 </Unit> 217 </Unit>
@@ -245,6 +245,9 @@ @@ -245,6 +245,9 @@
245 <Unit filename="src/lib3270/version.c"> 245 <Unit filename="src/lib3270/version.c">
246 <Option compilerVar="CC" /> 246 <Option compilerVar="CC" />
247 </Unit> 247 </Unit>
  248 + <Unit filename="src/lib3270/windows/event_dispatcher.c">
  249 + <Option compilerVar="CC" />
  250 + </Unit>
248 <Unit filename="src/lib3270/windows/resources.rc" /> 251 <Unit filename="src/lib3270/windows/resources.rc" />
249 <Unit filename="src/lib3270/windows/resources.rc.in" /> 252 <Unit filename="src/lib3270/windows/resources.rc.in" />
250 <Extensions> 253 <Extensions>
src/lib3270/iocalls.c
@@ -37,10 +37,10 @@ @@ -37,10 +37,10 @@
37 #include "utilc.h" 37 #include "utilc.h"
38 38
39 #define MILLION 1000000L 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 /*---[ Standard calls ]-------------------------------------------------------------------------------------*/ 45 /*---[ Standard calls ]-------------------------------------------------------------------------------------*/
46 46
@@ -199,6 +199,7 @@ static void * internal_add_poll(H3270 *session, int fd, LIB3270_IO_FLAG flag, vo @@ -199,6 +199,7 @@ static void * internal_add_poll(H3270 *session, int fd, LIB3270_IO_FLAG flag, vo
199 input_t *ip = (input_t *) lib3270_malloc(sizeof(input_t)); 199 input_t *ip = (input_t *) lib3270_malloc(sizeof(input_t));
200 200
201 ip->session = session; 201 ip->session = session;
  202 + ip->enabled = 1;
202 ip->fd = fd; 203 ip->fd = fd;
203 ip->flag = flag; 204 ip->flag = flag;
204 ip->userdata = userdata; 205 ip->userdata = userdata;
@@ -285,276 +286,6 @@ LIB3270_EXPORT void * lib3270_add_poll_fd(H3270 *session, int fd, LIB3270_IO_FL @@ -285,276 +286,6 @@ LIB3270_EXPORT void * lib3270_add_poll_fd(H3270 *session, int fd, LIB3270_IO_FL
285 return add_poll(session,fd,flag,call,userdata); 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 static int internal_wait(H3270 *hSession, int seconds) 289 static int internal_wait(H3270 *hSession, int seconds)
559 { 290 {
560 time_t end = time(0) + seconds; 291 time_t end = time(0) + seconds;
src/lib3270/linux/event_dispatcher.c 0 → 100644
@@ -0,0 +1,204 @@ @@ -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
@@ -279,8 +279,9 @@ typedef struct timeout @@ -279,8 +279,9 @@ typedef struct timeout
279 * @brief I/O events. 279 * @brief I/O events.
280 * 280 *
281 */ 281 */
282 -typedef struct input 282 +typedef struct _input_t
283 { 283 {
  284 + unsigned char enabled;
284 struct input * next; 285 struct input * next;
285 H3270 * session; 286 H3270 * session;
286 int fd; 287 int fd;
src/lib3270/windows/event_dispatcher.c 0 → 100644
@@ -0,0 +1,218 @@ @@ -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 +