Eliminate immediate_quit
This finally gets rid of immediate_quit (and surrounding infrustruture), as nothing sets it anymore. gdb_call_async_signal_handler was only necessary in order to handle immediate_quit. We can just call mark_async_signal_handler directly on all hosts now. In turn, we can clean up mingw-hdep.c's gdb_select a bit, as sigint_event / sigint_handler is no longer needed. gdb/ChangeLog: 2016-04-12 Pedro Alves <palves@redhat.com> * defs.h: Update comments on SIGINT handling. (immediate_quit): Delete declaration. * event-loop.c (call_async_signal_handler): Delete. * event-loop.h (call_async_signal_handler): Delete declaration. (mark_async_signal_handler): Update comments. (gdb_call_async_signal_handler): Delete declaration. * event-top.c (handle_sigint): Call mark_async_signal_handler instead of gdb_call_async_signal_handler. * exceptions.c (prepare_to_throw_exception): Remove reference to immediate_quit. (exception_fprintf): Remove comments about immediate_quit. * mingw-hdep.c (sigint_event, sigint_handler): Delete. (gdb_select): Don't wait on sigint_event. (gdb_call_async_signal_handler): Delete. (_initialize_mingw_hdep): Delete. * posix-hdep.c (gdb_call_async_signal_handler): Delete. * utils.c (immediate_quit): Delete.
This commit is contained in:
parent
048094accc
commit
585a46a2d0
9 changed files with 32 additions and 131 deletions
|
@ -1,3 +1,23 @@
|
||||||
|
2016-04-12 Pedro Alves <palves@redhat.com>
|
||||||
|
|
||||||
|
* defs.h: Update comments on SIGINT handling.
|
||||||
|
(immediate_quit): Delete declaration.
|
||||||
|
* event-loop.c (call_async_signal_handler): Delete.
|
||||||
|
* event-loop.h (call_async_signal_handler): Delete declaration.
|
||||||
|
(mark_async_signal_handler): Update comments.
|
||||||
|
(gdb_call_async_signal_handler): Delete declaration.
|
||||||
|
* event-top.c (handle_sigint): Call mark_async_signal_handler
|
||||||
|
instead of gdb_call_async_signal_handler.
|
||||||
|
* exceptions.c (prepare_to_throw_exception): Remove reference to
|
||||||
|
immediate_quit.
|
||||||
|
(exception_fprintf): Remove comments about immediate_quit.
|
||||||
|
* mingw-hdep.c (sigint_event, sigint_handler): Delete.
|
||||||
|
(gdb_select): Don't wait on sigint_event.
|
||||||
|
(gdb_call_async_signal_handler): Delete.
|
||||||
|
(_initialize_mingw_hdep): Delete.
|
||||||
|
* posix-hdep.c (gdb_call_async_signal_handler): Delete.
|
||||||
|
* utils.c (immediate_quit): Delete.
|
||||||
|
|
||||||
2016-04-12 Pedro Alves <palves@redhat.com>
|
2016-04-12 Pedro Alves <palves@redhat.com>
|
||||||
|
|
||||||
* defs.h (quit_handler_ftype, quit_handler)
|
* defs.h (quit_handler_ftype, quit_handler)
|
||||||
|
|
11
gdb/defs.h
11
gdb/defs.h
|
@ -125,11 +125,10 @@ extern char *python_libdir;
|
||||||
/* * Search path for separate debug files. */
|
/* * Search path for separate debug files. */
|
||||||
extern char *debug_file_directory;
|
extern char *debug_file_directory;
|
||||||
|
|
||||||
/* GDB has two methods for handling SIGINT. When immediate_quit is
|
/* GDB's SIGINT handler basically sets a flag; code that might take a
|
||||||
nonzero, a SIGINT results in an immediate longjmp out of the signal
|
long time before it gets back to the event loop, and which ought to
|
||||||
handler. Otherwise, SIGINT simply sets a flag; code that might
|
be interruptible, checks this flag using the QUIT macro, which, if
|
||||||
take a long time, and which ought to be interruptible, checks this
|
GDB has the terminal, throws a quit exception.
|
||||||
flag using the QUIT macro.
|
|
||||||
|
|
||||||
In addition to setting a flag, the SIGINT handler also marks a
|
In addition to setting a flag, the SIGINT handler also marks a
|
||||||
select/poll-able file descriptor as read-ready. That is used by
|
select/poll-able file descriptor as read-ready. That is used by
|
||||||
|
@ -176,8 +175,6 @@ extern void default_quit_handler (void);
|
||||||
/* Flag that function quit should call quit_force. */
|
/* Flag that function quit should call quit_force. */
|
||||||
extern volatile int sync_quit_force_run;
|
extern volatile int sync_quit_force_run;
|
||||||
|
|
||||||
extern int immediate_quit;
|
|
||||||
|
|
||||||
extern void quit (void);
|
extern void quit (void);
|
||||||
|
|
||||||
/* Helper for the QUIT macro. */
|
/* Helper for the QUIT macro. */
|
||||||
|
|
|
@ -911,15 +911,6 @@ create_async_signal_handler (sig_handler_func * proc,
|
||||||
return async_handler_ptr;
|
return async_handler_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Call the handler from HANDLER immediately. This function runs
|
|
||||||
signal handlers when returning to the event loop would be too
|
|
||||||
slow. */
|
|
||||||
void
|
|
||||||
call_async_signal_handler (struct async_signal_handler *handler)
|
|
||||||
{
|
|
||||||
(*handler->proc) (handler->client_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Mark the handler (ASYNC_HANDLER_PTR) as ready. This information
|
/* Mark the handler (ASYNC_HANDLER_PTR) as ready. This information
|
||||||
will be used when the handlers are invoked, after we have waited
|
will be used when the handlers are invoked, after we have waited
|
||||||
for some event. The caller of this function is the interrupt
|
for some event. The caller of this function is the interrupt
|
||||||
|
|
|
@ -91,16 +91,9 @@ extern int create_timer (int milliseconds,
|
||||||
gdb_client_data client_data);
|
gdb_client_data client_data);
|
||||||
extern void delete_timer (int id);
|
extern void delete_timer (int id);
|
||||||
|
|
||||||
/* Call the handler from HANDLER immediately. This function
|
/* Call the handler from HANDLER the next time through the event
|
||||||
runs signal handlers when returning to the event loop would be too
|
loop. */
|
||||||
slow. Do not call this directly; use gdb_call_async_signal_handler,
|
extern void mark_async_signal_handler (struct async_signal_handler *handler);
|
||||||
below, with IMMEDIATE_P == 1. */
|
|
||||||
void call_async_signal_handler (struct async_signal_handler *handler);
|
|
||||||
|
|
||||||
/* Call the handler from HANDLER the next time through the event loop.
|
|
||||||
Do not call this directly; use gdb_call_async_signal_handler,
|
|
||||||
below, with IMMEDIATE_P == 0. */
|
|
||||||
void mark_async_signal_handler (struct async_signal_handler *handler);
|
|
||||||
|
|
||||||
/* Returns true if HANDLER is marked ready. */
|
/* Returns true if HANDLER is marked ready. */
|
||||||
|
|
||||||
|
@ -111,17 +104,6 @@ extern int
|
||||||
|
|
||||||
extern void clear_async_signal_handler (struct async_signal_handler *handler);
|
extern void clear_async_signal_handler (struct async_signal_handler *handler);
|
||||||
|
|
||||||
/* Wrapper for the body of signal handlers. Call this function from
|
|
||||||
any SIGINT handler which needs to access GDB data structures or
|
|
||||||
escape via longjmp. If IMMEDIATE_P is set, this triggers either
|
|
||||||
immediately (for POSIX platforms), or from gdb_select (for
|
|
||||||
MinGW). If IMMEDIATE_P is clear, the handler will run the next
|
|
||||||
time we return to the event loop and any current select calls
|
|
||||||
will be interrupted. */
|
|
||||||
|
|
||||||
void gdb_call_async_signal_handler (struct async_signal_handler *handler,
|
|
||||||
int immediate_p);
|
|
||||||
|
|
||||||
/* Create and register an asynchronous event source in the event loop,
|
/* Create and register an asynchronous event source in the event loop,
|
||||||
and set PROC as its callback. CLIENT_DATA is passed as argument to
|
and set PROC as its callback. CLIENT_DATA is passed as argument to
|
||||||
PROC upon its invocation. Returns a pointer to an opaque structure
|
PROC upon its invocation. Returns a pointer to an opaque structure
|
||||||
|
|
|
@ -901,18 +901,11 @@ handle_sigint (int sig)
|
||||||
it may be quite a while before we get back to the event loop. So
|
it may be quite a while before we get back to the event loop. So
|
||||||
set quit_flag to 1 here. Then if QUIT is called before we get to
|
set quit_flag to 1 here. Then if QUIT is called before we get to
|
||||||
the event loop, we will unwind as expected. */
|
the event loop, we will unwind as expected. */
|
||||||
|
|
||||||
set_quit_flag ();
|
set_quit_flag ();
|
||||||
|
|
||||||
/* If immediate_quit is set, we go ahead and process the SIGINT right
|
/* In case nothing calls QUIT before the event loop is reached, the
|
||||||
away, even if we usually would defer this to the event loop. The
|
event loop handles it. */
|
||||||
assumption here is that it is safe to process ^C immediately if
|
mark_async_signal_handler (sigint_token);
|
||||||
immediate_quit is set. If we didn't, SIGINT would be really
|
|
||||||
processed only the next time through the event loop. To get to
|
|
||||||
that point, though, the command that we want to interrupt needs to
|
|
||||||
finish first, which is unacceptable. If immediate quit is not set,
|
|
||||||
we process SIGINT the next time through the loop, which is fine. */
|
|
||||||
gdb_call_async_signal_handler (sigint_token, immediate_quit);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See gdb_select.h. */
|
/* See gdb_select.h. */
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
void
|
void
|
||||||
prepare_to_throw_exception (void)
|
prepare_to_throw_exception (void)
|
||||||
{
|
{
|
||||||
immediate_quit = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -148,12 +147,7 @@ exception_fprintf (struct ui_file *file, struct gdb_exception e,
|
||||||
returned by catch_exceptions(). It is an internal_error() for
|
returned by catch_exceptions(). It is an internal_error() for
|
||||||
FUNC() to return a negative value.
|
FUNC() to return a negative value.
|
||||||
|
|
||||||
See exceptions.h for further usage details.
|
See exceptions.h for further usage details. */
|
||||||
|
|
||||||
Must not be called with immediate_quit in effect (bad things might
|
|
||||||
happen, say we got a signal in the middle of a memcpy to quit_return).
|
|
||||||
This is an OK restriction; with very few exceptions immediate_quit can
|
|
||||||
be replaced by judicious use of QUIT. */
|
|
||||||
|
|
||||||
/* MAYBE: cagney/1999-11-05: catch_errors() in conjunction with
|
/* MAYBE: cagney/1999-11-05: catch_errors() in conjunction with
|
||||||
error() et al. could maintain a set of flags that indicate the
|
error() et al. could maintain a set of flags that indicate the
|
||||||
|
|
|
@ -27,14 +27,6 @@
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
/* This event is signalled whenever an asynchronous SIGINT handler
|
|
||||||
needs to perform an action in the main thread. */
|
|
||||||
static HANDLE sigint_event;
|
|
||||||
|
|
||||||
/* When SIGINT_EVENT is signalled, gdb_select will call this
|
|
||||||
function. */
|
|
||||||
struct async_signal_handler *sigint_handler;
|
|
||||||
|
|
||||||
/* Return an absolute file name of the running GDB, if possible, or
|
/* Return an absolute file name of the running GDB, if possible, or
|
||||||
ARGV0 if not. The return value is in malloc'ed storage. */
|
ARGV0 if not. The return value is in malloc'ed storage. */
|
||||||
|
|
||||||
|
@ -120,8 +112,7 @@ gdb_select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gdb_assert (num_handles < MAXIMUM_WAIT_OBJECTS);
|
gdb_assert (num_handles <= MAXIMUM_WAIT_OBJECTS);
|
||||||
handles[num_handles++] = sigint_event;
|
|
||||||
|
|
||||||
event = WaitForMultipleObjects (num_handles,
|
event = WaitForMultipleObjects (num_handles,
|
||||||
handles,
|
handles,
|
||||||
|
@ -184,46 +175,5 @@ gdb_select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
||||||
while (RL_ISSTATE (RL_STATE_SIGHANDLER))
|
while (RL_ISSTATE (RL_STATE_SIGHANDLER))
|
||||||
Sleep (1);
|
Sleep (1);
|
||||||
|
|
||||||
if (h == sigint_event
|
|
||||||
|| WaitForSingleObject (sigint_event, 0) == WAIT_OBJECT_0)
|
|
||||||
{
|
|
||||||
if (sigint_handler != NULL)
|
|
||||||
call_async_signal_handler (sigint_handler);
|
|
||||||
|
|
||||||
if (num_ready == 0)
|
|
||||||
{
|
|
||||||
errno = EINTR;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return num_ready;
|
return num_ready;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wrapper for the body of signal handlers. On Windows systems, a
|
|
||||||
SIGINT handler runs in its own thread. We can't longjmp from
|
|
||||||
there, and we shouldn't even prompt the user. Delay HANDLER
|
|
||||||
until the main thread is next in gdb_select. */
|
|
||||||
|
|
||||||
void
|
|
||||||
gdb_call_async_signal_handler (struct async_signal_handler *handler,
|
|
||||||
int immediate_p)
|
|
||||||
{
|
|
||||||
if (immediate_p)
|
|
||||||
sigint_handler = handler;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mark_async_signal_handler (handler);
|
|
||||||
sigint_handler = NULL;
|
|
||||||
}
|
|
||||||
SetEvent (sigint_event);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -Wmissing-prototypes */
|
|
||||||
extern initialize_file_ftype _initialize_mingw_hdep;
|
|
||||||
|
|
||||||
void
|
|
||||||
_initialize_mingw_hdep (void)
|
|
||||||
{
|
|
||||||
sigint_event = CreateEvent (0, FALSE, FALSE, 0);
|
|
||||||
}
|
|
||||||
|
|
|
@ -30,16 +30,3 @@ gdb_select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
||||||
{
|
{
|
||||||
return select (n, readfds, writefds, exceptfds, timeout);
|
return select (n, readfds, writefds, exceptfds, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wrapper for the body of signal handlers. Nothing special needed on
|
|
||||||
POSIX platforms. */
|
|
||||||
|
|
||||||
void
|
|
||||||
gdb_call_async_signal_handler (struct async_signal_handler *handler,
|
|
||||||
int immediate_p)
|
|
||||||
{
|
|
||||||
if (immediate_p)
|
|
||||||
call_async_signal_handler (handler);
|
|
||||||
else
|
|
||||||
mark_async_signal_handler (handler);
|
|
||||||
}
|
|
||||||
|
|
13
gdb/utils.c
13
gdb/utils.c
|
@ -109,19 +109,6 @@ static int debug_timestamp = 0;
|
||||||
|
|
||||||
int job_control;
|
int job_control;
|
||||||
|
|
||||||
/* Nonzero means quit immediately if Control-C is typed now, rather
|
|
||||||
than waiting until QUIT is executed. Be careful in setting this;
|
|
||||||
code which executes with immediate_quit set has to be very careful
|
|
||||||
about being able to deal with being interrupted at any time. It is
|
|
||||||
almost always better to use QUIT; the only exception I can think of
|
|
||||||
is being able to quit out of a system call (using EINTR loses if
|
|
||||||
the SIGINT happens between the previous QUIT and the system call).
|
|
||||||
To immediately quit in the case in which a SIGINT happens between
|
|
||||||
the previous QUIT and setting immediate_quit (desirable anytime we
|
|
||||||
expect to block), call QUIT after setting immediate_quit. */
|
|
||||||
|
|
||||||
int immediate_quit;
|
|
||||||
|
|
||||||
/* Nonzero means that strings with character values >0x7F should be printed
|
/* Nonzero means that strings with character values >0x7F should be printed
|
||||||
as octal escapes. Zero means just print the value (e.g. it's an
|
as octal escapes. Zero means just print the value (e.g. it's an
|
||||||
international character, and the terminal or window can cope.) */
|
international character, and the terminal or window can cope.) */
|
||||||
|
|
Loading…
Reference in a new issue