summaryrefslogtreecommitdiff
path: root/ext/tcltklib/tcltklib.c
diff options
context:
space:
mode:
authornagai <nagai@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-06-09 18:09:11 +0000
committernagai <nagai@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-06-09 18:09:11 +0000
commitca02190d8887ecd852e4e3f18f3a3ea91e9c6f7a (patch)
treea0c22afb3f3b5477cf17a9b885c9c8fab9726e22 /ext/tcltklib/tcltklib.c
parent1a28365c0ad995a14d894824c2c4765d41416dab (diff)
fix : 100% CPU problem of Tk.mainloop
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3924 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/tcltklib/tcltklib.c')
-rw-r--r--ext/tcltklib/tcltklib.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/ext/tcltklib/tcltklib.c b/ext/tcltklib/tcltklib.c
index c8a3e7289d..9fa992e488 100644
--- a/ext/tcltklib/tcltklib.c
+++ b/ext/tcltklib/tcltklib.c
@@ -69,16 +69,21 @@ Tcl_Interp *current_interp;
* 'timer_tick' is a limit of one term of thread scheduling.
* If 'timer_tick' == 0, then not use the timer for thread scheduling.
*/
-#define DEFAULT_EVENT_LOOP_MAX 800/*counts*/
-#define DEFAULT_NO_EVENT_TICK 10/*counts*/
-#define DEFAULT_TIMER_TICK 0/*milliseconds*/
-#define DEFAULT_INTERRUPT_TIME 200/*milliseconds*/
+#define DEFAULT_EVENT_LOOP_MAX 800/*counts*/
+#define DEFAULT_NO_EVENT_TICK 10/*counts*/
+#define DEFAULT_NO_EVENT_WAIT 20/*milliseconds ( 1 -- 999 ) */
+#define WATCHDOG_INTERVAL 10/*milliseconds ( 1 -- 999 ) */
+#define DEFAULT_TIMER_TICK 0/*milliseconds*/
+#define NO_THREAD_INTERRUPT_TIME 200/*milliseconds*/
+
static int event_loop_max = DEFAULT_EVENT_LOOP_MAX;
static int no_event_tick = DEFAULT_NO_EVENT_TICK;
+static int no_event_wait = DEFAULT_NO_EVENT_WAIT;
static int timer_tick = DEFAULT_TIMER_TICK;
static int req_timer_tick = DEFAULT_TIMER_TICK;
static int run_timer_flag = 0;
+
#if TCL_MAJOR_VERSION >= 8
static int ip_ruby _((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST*));
#else
@@ -180,6 +185,10 @@ lib_mainloop_core(check_root_widget)
VALUE current = eventloop_thread;
int check = (check_root_widget == Qtrue);
int tick_counter;
+ struct timeval t;
+
+ t.tv_sec = (time_t)0;
+ t.tv_usec = (time_t)(no_event_wait*1000.0);
Tk_DeleteTimerHandler(timer_token);
run_timer_flag = 0;
@@ -194,7 +203,7 @@ lib_mainloop_core(check_root_widget)
if (rb_thread_alone()) {
DUMP1("no other thread");
if (timer_tick == 0) {
- timer_tick = DEFAULT_INTERRUPT_TIME;
+ timer_tick = NO_THREAD_INTERRUPT_TIME;
timer_token = Tk_CreateTimerHandler(timer_tick, _timer_for_tcl,
(ClientData)0);
}
@@ -219,6 +228,13 @@ lib_mainloop_core(check_root_widget)
tick_counter++;
} else {
tick_counter += no_event_tick;
+
+ DUMP1("check Root Widget");
+ if (check && Tk_GetNumMainWindows() == 0) {
+ return Qnil;
+ }
+
+ rb_thread_wait_for(t);
}
if (watchdog_thread != 0 && eventloop_thread != current) {
@@ -303,6 +319,10 @@ lib_watchdog_core(check_rootwidget)
VALUE evloop;
int check = (check_rootwidget == Qtrue);
ID stop = rb_intern("stop?");
+ struct timeval t;
+
+ t.tv_sec = (time_t)0;
+ t.tv_usec = (time_t)((WATCHDOG_INTERVAL)*1000.0);
/* check other watchdog thread */
if (watchdog_thread != 0) {
@@ -325,7 +345,8 @@ lib_watchdog_core(check_rootwidget)
DUMP2("create new eventloop thread %lx", evloop);
rb_thread_run(evloop);
} else {
- rb_thread_schedule();
+ rb_thread_wait_for(t);
+ /* rb_thread_schedule(); */
}
} while(!check || Tk_GetNumMainWindows() != 0);