diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 12 | ||||
| -rw-r--r-- | src/w32proc.c | 38 |
2 files changed, 38 insertions, 12 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index d72091c0ed6..9caa5113444 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,15 @@ | |||
| 1 | 2012-11-14 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * w32proc.c (timer_loop): Make sure SuspendThread and ResumeThread | ||
| 4 | use the same value of thread handle. | ||
| 5 | (start_timer_thread): If the timer thread exited (due to error), | ||
| 6 | clean up by closing the two handles it used. Duplicate the caller | ||
| 7 | thread's handle here, so it gets duplicated only once, when | ||
| 8 | launching the timer thread. Set priority of the timer thread, not | ||
| 9 | the caller thread. | ||
| 10 | (getitimer): Don't duplicate the caller thread's handle here. | ||
| 11 | (Bug#12832) | ||
| 12 | |||
| 1 | 2012-11-13 Jan Djärv <jan.h.d@swipnet.se> | 13 | 2012-11-13 Jan Djärv <jan.h.d@swipnet.se> |
| 2 | 14 | ||
| 3 | * nsterm.m (hold_event): Send SIGIO to make sure ns_read_socket is | 15 | * nsterm.m (hold_event): Send SIGIO to make sure ns_read_socket is |
diff --git a/src/w32proc.c b/src/w32proc.c index adef7651b8c..e3c54fe5460 100644 --- a/src/w32proc.c +++ b/src/w32proc.c | |||
| @@ -425,13 +425,14 @@ timer_loop (LPVOID arg) | |||
| 425 | /* Simulate a signal delivered to the thread which installed | 425 | /* Simulate a signal delivered to the thread which installed |
| 426 | the timer, by suspending that thread while the handler | 426 | the timer, by suspending that thread while the handler |
| 427 | runs. */ | 427 | runs. */ |
| 428 | DWORD result = SuspendThread (itimer->caller_thread); | 428 | HANDLE th = itimer->caller_thread; |
| 429 | DWORD result = SuspendThread (th); | ||
| 429 | 430 | ||
| 430 | if (result == (DWORD)-1) | 431 | if (result == (DWORD)-1) |
| 431 | return 2; | 432 | return 2; |
| 432 | 433 | ||
| 433 | handler (sig); | 434 | handler (sig); |
| 434 | ResumeThread (itimer->caller_thread); | 435 | ResumeThread (th); |
| 435 | } | 436 | } |
| 436 | 437 | ||
| 437 | /* Update expiration time and loop. */ | 438 | /* Update expiration time and loop. */ |
| @@ -556,6 +557,7 @@ static int | |||
| 556 | start_timer_thread (int which) | 557 | start_timer_thread (int which) |
| 557 | { | 558 | { |
| 558 | DWORD exit_code; | 559 | DWORD exit_code; |
| 560 | HANDLE th; | ||
| 559 | struct itimer_data *itimer = | 561 | struct itimer_data *itimer = |
| 560 | (which == ITIMER_REAL) ? &real_itimer : &prof_itimer; | 562 | (which == ITIMER_REAL) ? &real_itimer : &prof_itimer; |
| 561 | 563 | ||
| @@ -564,9 +566,29 @@ start_timer_thread (int which) | |||
| 564 | && exit_code == STILL_ACTIVE) | 566 | && exit_code == STILL_ACTIVE) |
| 565 | return 0; | 567 | return 0; |
| 566 | 568 | ||
| 569 | /* Clean up after possibly exited thread. */ | ||
| 570 | if (itimer->timer_thread) | ||
| 571 | { | ||
| 572 | CloseHandle (itimer->timer_thread); | ||
| 573 | itimer->timer_thread = NULL; | ||
| 574 | } | ||
| 575 | if (itimer->caller_thread) | ||
| 576 | { | ||
| 577 | CloseHandle (itimer->caller_thread); | ||
| 578 | itimer->caller_thread = NULL; | ||
| 579 | } | ||
| 580 | |||
| 567 | /* Start a new thread. */ | 581 | /* Start a new thread. */ |
| 582 | if (!DuplicateHandle (GetCurrentProcess (), GetCurrentThread (), | ||
| 583 | GetCurrentProcess (), &th, 0, FALSE, | ||
| 584 | DUPLICATE_SAME_ACCESS)) | ||
| 585 | { | ||
| 586 | errno = ESRCH; | ||
| 587 | return -1; | ||
| 588 | } | ||
| 568 | itimer->terminate = 0; | 589 | itimer->terminate = 0; |
| 569 | itimer->type = which; | 590 | itimer->type = which; |
| 591 | itimer->caller_thread = th; | ||
| 570 | /* Request that no more than 64KB of stack be reserved for this | 592 | /* Request that no more than 64KB of stack be reserved for this |
| 571 | thread, to avoid reserving too much memory, which would get in | 593 | thread, to avoid reserving too much memory, which would get in |
| 572 | the way of threads we start to wait for subprocesses. See also | 594 | the way of threads we start to wait for subprocesses. See also |
| @@ -585,7 +607,7 @@ start_timer_thread (int which) | |||
| 585 | /* This is needed to make sure that the timer thread running for | 607 | /* This is needed to make sure that the timer thread running for |
| 586 | profiling gets CPU as soon as the Sleep call terminates. */ | 608 | profiling gets CPU as soon as the Sleep call terminates. */ |
| 587 | if (which == ITIMER_PROF) | 609 | if (which == ITIMER_PROF) |
| 588 | SetThreadPriority (itimer->caller_thread, THREAD_PRIORITY_TIME_CRITICAL); | 610 | SetThreadPriority (itimer->timer_thread, THREAD_PRIORITY_TIME_CRITICAL); |
| 589 | 611 | ||
| 590 | return 0; | 612 | return 0; |
| 591 | } | 613 | } |
| @@ -620,17 +642,9 @@ getitimer (int which, struct itimerval *value) | |||
| 620 | 642 | ||
| 621 | itimer = (which == ITIMER_REAL) ? &real_itimer : &prof_itimer; | 643 | itimer = (which == ITIMER_REAL) ? &real_itimer : &prof_itimer; |
| 622 | 644 | ||
| 623 | if (!DuplicateHandle (GetCurrentProcess (), GetCurrentThread (), | ||
| 624 | GetCurrentProcess (), &itimer->caller_thread, 0, | ||
| 625 | FALSE, DUPLICATE_SAME_ACCESS)) | ||
| 626 | { | ||
| 627 | errno = ESRCH; | ||
| 628 | return -1; | ||
| 629 | } | ||
| 630 | |||
| 631 | ticks_now = w32_get_timer_time ((which == ITIMER_REAL) | 645 | ticks_now = w32_get_timer_time ((which == ITIMER_REAL) |
| 632 | ? NULL | 646 | ? NULL |
| 633 | : itimer->caller_thread); | 647 | : GetCurrentThread ()); |
| 634 | 648 | ||
| 635 | t_expire = &itimer->expire; | 649 | t_expire = &itimer->expire; |
| 636 | t_reload = &itimer->reload; | 650 | t_reload = &itimer->reload; |