Browse Source
This pulls out the implementation of an event pipe used to implement target async support in both linux-low.cc (gdbserver) and linux-nat.c (gdb). This will be used to replace the existing event pipe in linux-low.cc and linux-nat.c in future commits. Co-Authored-By: Lancelot SIX <lsix@lancelotsix.com>gdb-12-branch
6 changed files with 190 additions and 3 deletions
@ -0,0 +1,101 @@ |
|||
/* Event pipe for GDB, the GNU debugger.
|
|||
|
|||
Copyright (C) 2021 Free Software Foundation, Inc. |
|||
|
|||
This file is part of GDB. |
|||
|
|||
This program is free software; you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation; either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
This program is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|||
|
|||
#include "gdbsupport/common-defs.h" |
|||
#include "gdbsupport/event-pipe.h" |
|||
#include "gdbsupport/filestuff.h" |
|||
|
|||
#include <errno.h> |
|||
#include <fcntl.h> |
|||
#include <unistd.h> |
|||
|
|||
event_pipe::~event_pipe () |
|||
{ |
|||
if (is_open ()) |
|||
close (); |
|||
} |
|||
|
|||
/* See event-pipe.h. */ |
|||
|
|||
bool |
|||
event_pipe::open () |
|||
{ |
|||
if (is_open ()) |
|||
return false; |
|||
|
|||
if (gdb_pipe_cloexec (m_fds) == -1) |
|||
return false; |
|||
|
|||
if (fcntl (m_fds[0], F_SETFL, O_NONBLOCK) == -1 |
|||
|| fcntl (m_fds[1], F_SETFL, O_NONBLOCK) == -1) |
|||
{ |
|||
close (); |
|||
return false; |
|||
} |
|||
|
|||
return true; |
|||
} |
|||
|
|||
/* See event-pipe.h. */ |
|||
|
|||
void |
|||
event_pipe::close () |
|||
{ |
|||
::close (m_fds[0]); |
|||
::close (m_fds[1]); |
|||
m_fds[0] = -1; |
|||
m_fds[1] = -1; |
|||
} |
|||
|
|||
/* See event-pipe.h. */ |
|||
|
|||
void |
|||
event_pipe::flush () |
|||
{ |
|||
int ret; |
|||
char buf; |
|||
|
|||
do |
|||
{ |
|||
ret = read (m_fds[0], &buf, 1); |
|||
} |
|||
while (ret >= 0 || (ret == -1 && errno == EINTR)); |
|||
} |
|||
|
|||
/* See event-pipe.h. */ |
|||
|
|||
void |
|||
event_pipe::mark () |
|||
{ |
|||
int ret; |
|||
|
|||
/* It doesn't really matter what the pipe contains, as long we end
|
|||
up with something in it. Might as well flush the previous |
|||
left-overs. */ |
|||
flush (); |
|||
|
|||
do |
|||
{ |
|||
ret = write (m_fds[1], "+", 1); |
|||
} |
|||
while (ret == -1 && errno == EINTR); |
|||
|
|||
/* Ignore EAGAIN. If the pipe is full, the event loop will already
|
|||
be awakened anyway. */ |
|||
} |
|||
@ -0,0 +1,60 @@ |
|||
/* Event pipe for GDB, the GNU debugger.
|
|||
|
|||
Copyright (C) 2021 Free Software Foundation, Inc. |
|||
|
|||
This file is part of GDB. |
|||
|
|||
This program is free software; you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation; either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
This program is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|||
|
|||
#ifndef COMMON_EVENT_PIPE_H |
|||
#define COMMON_EVENT_PIPE_H |
|||
|
|||
/* An event pipe used as a waitable file in the event loop in place of
|
|||
some other event associated with a signal. The handler for the |
|||
signal marks the event pipe to force a wakeup in the event loop. |
|||
This uses the well-known self-pipe trick. */ |
|||
|
|||
class event_pipe |
|||
{ |
|||
public: |
|||
event_pipe() = default; |
|||
~event_pipe(); |
|||
|
|||
DISABLE_COPY_AND_ASSIGN (event_pipe); |
|||
|
|||
/* Create a new pipe. */ |
|||
bool open (); |
|||
|
|||
/* Close the pipe. */ |
|||
void close (); |
|||
|
|||
/* True if the event pipe has been opened. */ |
|||
bool is_open () const |
|||
{ return m_fds[0] != -1; } |
|||
|
|||
/* The file descriptor of the waitable file to use in the event
|
|||
loop. */ |
|||
int event_fd () const |
|||
{ return m_fds[0]; } |
|||
|
|||
/* Flush the event pipe. */ |
|||
void flush (); |
|||
|
|||
/* Put something in the pipe, so the event loop wakes up. */ |
|||
void mark (); |
|||
private: |
|||
int m_fds[2] = { -1, -1 }; |
|||
}; |
|||
|
|||
#endif /* COMMON_EVENT_PIPE_H */ |
|||
Loading…
Reference in new issue