Commit 3ecfb738557e00b5dfd1d6bddabcdb2d113996e1

Authored by Perry Werneck
1 parent 492a4559

Refactoring timer engine to avoid an abnormal delay when calling

wait_for_ready on windows.
src/core/ctlr.c
... ... @@ -2696,101 +2696,3 @@ enum dbcs_state ctlr_dbcs_state(int baddr)
2696 2696 return dbcs? ea_buf[baddr].db: DBCS_NONE;
2697 2697 }
2698 2698 #endif /*]*/
2699   -
2700   -/*
2701   - * Transaction timing. The time between sending an interrupt (PF, PA, Enter,
2702   - * Clear) and the host unlocking the keyboard is indicated on the status line
2703   - * to an accuracy of 0.1 seconds. If we don't repaint the screen before we see
2704   - * the unlock, the time should be fairly accurate.
2705   - */
2706   -//static struct timeval t_start;
2707   -// static Boolean ticking = False;
2708   -//static Boolean mticking = False;
2709   -//static void * tick_id;
2710   -//static struct timeval t_want;
2711   -
2712   -/*
2713   -/// @brief Return the difference in milliseconds between two timevals.
2714   -static long delta_msec(struct timeval *t1, struct timeval *t0)
2715   -{
2716   - return (t1->tv_sec - t0->tv_sec) * 1000 +
2717   - (t1->tv_usec - t0->tv_usec + 500) / 1000;
2718   -}
2719   -
2720   -static int keep_ticking(H3270 *hSession)
2721   -{
2722   - struct timeval t1;
2723   - long msec;
2724   -
2725   - do
2726   - {
2727   - (void) gettimeofday(&t1, (struct timezone *) 0);
2728   - hSession->t_want.tv_sec++;
2729   - msec = delta_msec(&hSession->t_want, &t1);
2730   - } while (msec <= 0);
2731   -
2732   - status_timing(hSession,&hSession->t_start, &t1);
2733   -
2734   - return 1;
2735   -}
2736   -*/
2737   -
2738   -/*
2739   -void ticking_start(H3270 *hSession, Boolean anyway)
2740   -{
2741   - CHECK_SESSION_HANDLE(hSession);
2742   -
2743   - if(hSession->cbk.set_timer)
2744   - {
2745   - if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SHOW_TIMING) || anyway)
2746   - hSession->cbk.set_timer(hSession,1);
2747   - }
2748   - else
2749   - {
2750   - (void) gettimeofday(&hSession->t_start, (struct timezone *) 0);
2751   -
2752   - hSession->mticking = 1;
2753   -
2754   - if (!lib3270_get_toggle(hSession,LIB3270_TOGGLE_SHOW_TIMING) && !anyway)
2755   - return;
2756   -
2757   - status_untiming(hSession);
2758   -
2759   - if (hSession->ticking)
2760   - RemoveTimer(hSession, hSession->tick_id);
2761   -
2762   - hSession->ticking = 1;
2763   - hSession->tick_id = AddTimer(1000, hSession, keep_ticking);
2764   - hSession->t_want = hSession->t_start;
2765   - }
2766   -
2767   -}
2768   -*/
2769   -
2770   -/*
2771   -static void ticking_stop(H3270 *hSession)
2772   -{
2773   - CHECK_SESSION_HANDLE(hSession);
2774   -
2775   - if(hSession->cbk.set_timer)
2776   - {
2777   - hSession->cbk.set_timer(hSession,0);
2778   - }
2779   - else
2780   - {
2781   - struct timeval t1;
2782   -
2783   - (void) gettimeofday(&t1, (struct timezone *) 0);
2784   - if (hSession->mticking)
2785   - hSession->mticking = 0;
2786   - else
2787   - return;
2788   -
2789   - if (!hSession->ticking)
2790   - return;
2791   - RemoveTimer(hSession, hSession->tick_id);
2792   - hSession->ticking = 0;
2793   - status_timing(hSession,&hSession->t_start, &t1);
2794   - }
2795   -}
2796   -*/
... ...
src/core/linux/event_dispatcher.c
... ... @@ -188,10 +188,14 @@ retry:
188 188 if (t->tv.tv_sec < now.tv_sec ||(t->tv.tv_sec == now.tv_sec && t->tv.tv_usec < now.tv_usec))
189 189 {
190 190 t->in_play = True;
191   - (*t->proc)(hSession,t->userdata);
  191 +
  192 + if((*t->proc)(hSession,t->userdata) == 0)
  193 + lib3270_linked_list_delete_node(&hSession->timeouts,t);
  194 + else
  195 + t->in_play = False;
  196 +
192 197 processed_any = True;
193 198  
194   - lib3270_linked_list_delete_node(&hSession->timeouts,t);
195 199  
196 200 }
197 201 else
... ...
src/core/wait.c
... ... @@ -31,9 +31,16 @@
31 31 #include <lib3270/log.h>
32 32 #include <lib3270/trace.h>
33 33 #include "kybdc.h"
  34 +#include "utilc.h"
34 35  
35 36 /*---[ Implement ]------------------------------------------------------------------------------------------*/
36 37  
  38 +static int timer_expired(H3270 GNUC_UNUSED(*hSession), void *userdata)
  39 +{
  40 + *((int *) userdata) = errno = ETIMEDOUT;
  41 + return 1; // Keep timer handle.
  42 +}
  43 +
37 44 LIB3270_EXPORT int lib3270_wait_for_update(H3270 GNUC_UNUSED(*hSession), int GNUC_UNUSED(seconds))
38 45 {
39 46 return errno = ENOTSUP;
... ... @@ -41,57 +48,70 @@ LIB3270_EXPORT int lib3270_wait_for_update(H3270 GNUC_UNUSED(*hSession), int GNU
41 48  
42 49 LIB3270_EXPORT int lib3270_wait_for_ready(H3270 *hSession, int seconds)
43 50 {
44   - time_t end = time(0)+seconds;
45   -
46   - if(lib3270_is_disconnected(hSession))
47   - return errno = ENOTCONN;
48   -
49   - lib3270_main_iterate(hSession,0);
  51 + FAIL_IF_NOT_ONLINE(hSession);
50 52  
51   - // Keyboard is locked by operator error, fails!
52   - if(hSession->kybdlock && KYBDLOCK_IS_OERR(hSession))
53   - return errno = EPERM;
  53 + int rc = 0;
  54 + void * timer = AddTimer(seconds * 1000, hSession, timer_expired, &rc);
54 55  
55   - do
  56 + while(!rc)
56 57 {
57 58 if(!lib3270_get_lock_status(hSession))
58   - return 0;
  59 + {
  60 + break;
  61 + }
59 62  
60 63 if(lib3270_is_disconnected(hSession))
61   - return errno = ENOTCONN;
  64 + {
  65 + rc = errno = ENOTCONN;
  66 + break;
  67 + }
62 68  
63   - lib3270_main_iterate(hSession,1);
  69 + if(hSession->kybdlock && KYBDLOCK_IS_OERR(hSession))
  70 + {
  71 + rc = errno = EPERM;
  72 + break;
  73 + }
64 74  
  75 + lib3270_main_iterate(hSession,1);
65 76 }
66   - while(time(0) < end);
  77 + RemoveTimer(hSession,timer);
  78 +
  79 + return rc;
67 80  
68   - return errno = ETIMEDOUT;
69 81 }
70 82  
71 83 int lib3270_wait_for_string(H3270 *hSession, const char *key, int seconds)
72 84 {
73   - time_t end = time(0)+seconds;
74   -
75 85 FAIL_IF_NOT_ONLINE(hSession);
76 86  
77   - lib3270_main_iterate(hSession,0);
  87 + int rc = 0;
  88 + void * timer = AddTimer(seconds * 1000, hSession, timer_expired, &rc);
78 89  
79   - do
  90 + while(!rc)
80 91 {
81 92 // Keyboard is locked by operator error, fails!
82 93 if(hSession->kybdlock && KYBDLOCK_IS_OERR(hSession))
83   - return errno = EPERM;
  94 + {
  95 + rc = errno = EPERM;
  96 + break;
  97 + }
84 98  
85 99 if(!lib3270_is_connected(hSession))
86   - return errno = ENOTCONN;
  100 + {
  101 + rc = errno = ENOTCONN;
  102 + break;
  103 + }
87 104  
88 105 char * contents = lib3270_get_string_at_address(hSession, 0, -1, 0);
89 106 if(!contents)
90   - return errno;
  107 + {
  108 + rc = errno;
  109 + break;
  110 + }
91 111  
92 112 if(strstr(contents,key)) {
93 113 lib3270_free(contents);
94   - return 0;
  114 + break;
95 115 }
96 116  
97 117 lib3270_free(contents);
... ... @@ -99,40 +119,48 @@ int lib3270_wait_for_string(H3270 *hSession, const char *key, int seconds)
99 119 lib3270_main_iterate(hSession,1);
100 120  
101 121 }
102   - while(time(0) < end);
  122 + RemoveTimer(hSession,timer);
  123 +
  124 + return rc;
103 125  
104   - return errno = ETIMEDOUT;
105 126 }
106 127  
107 128 int lib3270_wait_for_string_at_address(H3270 *hSession, int baddr, const char *key, int seconds)
108 129 {
109   - time_t end = time(0)+seconds;
110   -
111 130 FAIL_IF_NOT_ONLINE(hSession);
112 131  
113   - lib3270_main_iterate(hSession,0);
114   -
115 132 if(baddr < 0)
116 133 baddr = lib3270_get_cursor_address(hSession);
117 134  
118   - do
  135 + int rc = 0;
  136 + void * timer = AddTimer(seconds * 1000, hSession, timer_expired, &rc);
  137 +
  138 + while(!rc)
119 139 {
120 140 // Keyboard is locked by operator error, fails!
121 141 if(hSession->kybdlock && KYBDLOCK_IS_OERR(hSession))
122   - return errno = EPERM;
  142 + {
  143 + rc = errno = EPERM;
  144 + break;
  145 + }
123 146  
124 147 if(!lib3270_is_connected(hSession))
125   - return errno = ENOTCONN;
  148 + {
  149 + rc = errno = ENOTCONN;
  150 + break;
  151 + }
126 152  
127 153 if(lib3270_cmp_string_at_address(hSession, baddr, key, 0) == 0)
128   - return 0;
  154 + {
  155 + break;
  156 + }
129 157  
130 158 lib3270_main_iterate(hSession,1);
131 159  
132 160 }
133   - while(time(0) < end);
  161 + RemoveTimer(hSession,timer);
134 162  
135   - return errno = ETIMEDOUT;
  163 + return rc;
136 164  
137 165 }
138 166  
... ...
src/include/utilc.h
... ... @@ -17,22 +17,11 @@
17 17 * @brief Global declarations for util.c.
18 18 */
19 19  
20   -LIB3270_INTERNAL char *ctl_see(int c);
  20 +LIB3270_INTERNAL char * ctl_see(int c);
21 21  
22   - /*
23   -LIB3270_INTERNAL void add_resource(const char *name, const char *value);
24   -LIB3270_INTERNAL const char *get_message(const char *key);
25   -LIB3270_INTERNAL const char *get_fresource(H3270 *hSession, const char *fmt, ...) LIB3270_GNUC_FORMAT(2, 3);
26   -LIB3270_INTERNAL const char *get_resource(H3270 *hSession, const char *name);
27   -LIB3270_INTERNAL int split_dbcs_resource(const char *value, char sep, char **part1, char **part2);
28   -LIB3270_INTERNAL int split_dresource(char **st, char **left, char **right);
29   -LIB3270_INTERNAL int split_lresource(char **st, char **value);
30   -LIB3270_INTERNAL char *strip_whitespace(const char *s);
31   -*/
32   -
33   -LIB3270_INTERNAL char *xs_buffer(const char *fmt, ...) LIB3270_GNUC_FORMAT(1, 2);
34   -LIB3270_INTERNAL void xs_error(const char *fmt, ...) LIB3270_GNUC_FORMAT(1, 2);
35   -LIB3270_INTERNAL void xs_warning(const char *fmt, ...) LIB3270_GNUC_FORMAT(1, 2);
  22 +LIB3270_INTERNAL char * xs_buffer(const char *fmt, ...) LIB3270_GNUC_FORMAT(1, 2);
  23 +LIB3270_INTERNAL void xs_error(const char *fmt, ...) LIB3270_GNUC_FORMAT(1, 2);
  24 +LIB3270_INTERNAL void xs_warning(const char *fmt, ...) LIB3270_GNUC_FORMAT(1, 2);
36 25  
37 26 LIB3270_INTERNAL void * AddInput(int, H3270 *session, void (*fn)(H3270 *session));
38 27 LIB3270_INTERNAL void * AddOutput(int, H3270 *session, void (*fn)(H3270 *session));
... ... @@ -42,24 +31,6 @@ LIB3270_INTERNAL void RemoveSource(H3270 *session, void *cookie);
42 31 LIB3270_INTERNAL void * AddTimer(unsigned long msec, H3270 *session, int (*fn)(H3270 *session, void *userdata), void *userdata);
43 32 LIB3270_INTERNAL void RemoveTimer(H3270 *session, void *cookie);
44 33  
45   -// LIB3270_INTERNAL const char * KeysymToString(KeySym k);
46   -
47   -// LIB3270_INTERNAL int read_resource_file(const char *filename, Boolean fatal);
48   -// LIB3270_INTERNAL Boolean split_hier(char *label, char **base, char ***parents);
49   -
50   -/*
51   -typedef struct {
52   - char *buf;
53   - int alloc_len;
54   - int cur_len;
55   -} rpf_t;
56   -
57   -LIB3270_INTERNAL void rpf_init(rpf_t *r);
58   -LIB3270_INTERNAL void rpf_reset(rpf_t *r);
59   -LIB3270_INTERNAL void rpf(rpf_t *r, char *fmt, ...) LIB3270_GNUC_FORMAT(2, 3);
60   -LIB3270_INTERNAL void rpf_free(rpf_t *r);
61   -*/
62   -
63 34 /**
64 35 * @brief "unescape" text (Replaces %value for corresponding character).
65 36 *
... ... @@ -71,7 +42,7 @@ LIB3270_INTERNAL void rpf_free(rpf_t *r);
71 42 LIB3270_INTERNAL char * lib3270_unescape(const char *text);
72 43  
73 44 /**
74   - * @brief Compare strings ignoring non alfanumeric chars.
  45 + * @brief Compare strings ignoring non alphanumeric chars.
75 46 *
76 47 * @param s1 First string.
77 48 * @param s2 Second string.
... ...