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,101 +2696,3 @@ enum dbcs_state ctlr_dbcs_state(int baddr)
2696 return dbcs? ea_buf[baddr].db: DBCS_NONE; 2696 return dbcs? ea_buf[baddr].db: DBCS_NONE;
2697 } 2697 }
2698 #endif /*]*/ 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,10 +188,14 @@ retry:
188 if (t->tv.tv_sec < now.tv_sec ||(t->tv.tv_sec == now.tv_sec && t->tv.tv_usec < now.tv_usec)) 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 t->in_play = True; 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 processed_any = True; 197 processed_any = True;
193 198
194 - lib3270_linked_list_delete_node(&hSession->timeouts,t);  
195 199
196 } 200 }
197 else 201 else
src/core/wait.c
@@ -31,9 +31,16 @@ @@ -31,9 +31,16 @@
31 #include <lib3270/log.h> 31 #include <lib3270/log.h>
32 #include <lib3270/trace.h> 32 #include <lib3270/trace.h>
33 #include "kybdc.h" 33 #include "kybdc.h"
  34 +#include "utilc.h"
34 35
35 /*---[ Implement ]------------------------------------------------------------------------------------------*/ 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 LIB3270_EXPORT int lib3270_wait_for_update(H3270 GNUC_UNUSED(*hSession), int GNUC_UNUSED(seconds)) 44 LIB3270_EXPORT int lib3270_wait_for_update(H3270 GNUC_UNUSED(*hSession), int GNUC_UNUSED(seconds))
38 { 45 {
39 return errno = ENOTSUP; 46 return errno = ENOTSUP;
@@ -41,57 +48,70 @@ LIB3270_EXPORT int lib3270_wait_for_update(H3270 GNUC_UNUSED(*hSession), int GNU @@ -41,57 +48,70 @@ LIB3270_EXPORT int lib3270_wait_for_update(H3270 GNUC_UNUSED(*hSession), int GNU
41 48
42 LIB3270_EXPORT int lib3270_wait_for_ready(H3270 *hSession, int seconds) 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 if(!lib3270_get_lock_status(hSession)) 58 if(!lib3270_get_lock_status(hSession))
58 - return 0; 59 + {
  60 + break;
  61 + }
59 62
60 if(lib3270_is_disconnected(hSession)) 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 int lib3270_wait_for_string(H3270 *hSession, const char *key, int seconds) 83 int lib3270_wait_for_string(H3270 *hSession, const char *key, int seconds)
72 { 84 {
73 - time_t end = time(0)+seconds;  
74 -  
75 FAIL_IF_NOT_ONLINE(hSession); 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 // Keyboard is locked by operator error, fails! 92 // Keyboard is locked by operator error, fails!
82 if(hSession->kybdlock && KYBDLOCK_IS_OERR(hSession)) 93 if(hSession->kybdlock && KYBDLOCK_IS_OERR(hSession))
83 - return errno = EPERM; 94 + {
  95 + rc = errno = EPERM;
  96 + break;
  97 + }
84 98
85 if(!lib3270_is_connected(hSession)) 99 if(!lib3270_is_connected(hSession))
86 - return errno = ENOTCONN; 100 + {
  101 + rc = errno = ENOTCONN;
  102 + break;
  103 + }
87 104
88 char * contents = lib3270_get_string_at_address(hSession, 0, -1, 0); 105 char * contents = lib3270_get_string_at_address(hSession, 0, -1, 0);
89 if(!contents) 106 if(!contents)
90 - return errno; 107 + {
  108 + rc = errno;
  109 + break;
  110 + }
91 111
92 if(strstr(contents,key)) { 112 if(strstr(contents,key)) {
93 lib3270_free(contents); 113 lib3270_free(contents);
94 - return 0; 114 + break;
95 } 115 }
96 116
97 lib3270_free(contents); 117 lib3270_free(contents);
@@ -99,40 +119,48 @@ int lib3270_wait_for_string(H3270 *hSession, const char *key, int seconds) @@ -99,40 +119,48 @@ int lib3270_wait_for_string(H3270 *hSession, const char *key, int seconds)
99 lib3270_main_iterate(hSession,1); 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 int lib3270_wait_for_string_at_address(H3270 *hSession, int baddr, const char *key, int seconds) 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 FAIL_IF_NOT_ONLINE(hSession); 130 FAIL_IF_NOT_ONLINE(hSession);
112 131
113 - lib3270_main_iterate(hSession,0);  
114 -  
115 if(baddr < 0) 132 if(baddr < 0)
116 baddr = lib3270_get_cursor_address(hSession); 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 // Keyboard is locked by operator error, fails! 140 // Keyboard is locked by operator error, fails!
121 if(hSession->kybdlock && KYBDLOCK_IS_OERR(hSession)) 141 if(hSession->kybdlock && KYBDLOCK_IS_OERR(hSession))
122 - return errno = EPERM; 142 + {
  143 + rc = errno = EPERM;
  144 + break;
  145 + }
123 146
124 if(!lib3270_is_connected(hSession)) 147 if(!lib3270_is_connected(hSession))
125 - return errno = ENOTCONN; 148 + {
  149 + rc = errno = ENOTCONN;
  150 + break;
  151 + }
126 152
127 if(lib3270_cmp_string_at_address(hSession, baddr, key, 0) == 0) 153 if(lib3270_cmp_string_at_address(hSession, baddr, key, 0) == 0)
128 - return 0; 154 + {
  155 + break;
  156 + }
129 157
130 lib3270_main_iterate(hSession,1); 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,22 +17,11 @@
17 * @brief Global declarations for util.c. 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 LIB3270_INTERNAL void * AddInput(int, H3270 *session, void (*fn)(H3270 *session)); 26 LIB3270_INTERNAL void * AddInput(int, H3270 *session, void (*fn)(H3270 *session));
38 LIB3270_INTERNAL void * AddOutput(int, H3270 *session, void (*fn)(H3270 *session)); 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,24 +31,6 @@ LIB3270_INTERNAL void RemoveSource(H3270 *session, void *cookie);
42 LIB3270_INTERNAL void * AddTimer(unsigned long msec, H3270 *session, int (*fn)(H3270 *session, void *userdata), void *userdata); 31 LIB3270_INTERNAL void * AddTimer(unsigned long msec, H3270 *session, int (*fn)(H3270 *session, void *userdata), void *userdata);
43 LIB3270_INTERNAL void RemoveTimer(H3270 *session, void *cookie); 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 * @brief "unescape" text (Replaces %value for corresponding character). 35 * @brief "unescape" text (Replaces %value for corresponding character).
65 * 36 *
@@ -71,7 +42,7 @@ LIB3270_INTERNAL void rpf_free(rpf_t *r); @@ -71,7 +42,7 @@ LIB3270_INTERNAL void rpf_free(rpf_t *r);
71 LIB3270_INTERNAL char * lib3270_unescape(const char *text); 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 * @param s1 First string. 47 * @param s1 First string.
77 * @param s2 Second string. 48 * @param s2 Second string.