Commit 83e47afa267040a24ed363972ef709f99a92f5e3

Authored by Perry Werneck
1 parent 5da874ff

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

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;
... ...
src/lib3270/linux/event_dispatcher.c 0 → 100644
... ... @@ -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 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 285 struct input * next;
285 286 H3270 * session;
286 287 int fd;
... ...
src/lib3270/windows/event_dispatcher.c 0 → 100644
... ... @@ -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 +
... ...