Commit 8fc6dbfa authored by Pavel Emelyanov's avatar Pavel Emelyanov

files: Formalize fd restore priorities

There are places when we have to select which fd to ->open
and which to ->receive. To avoid deadlocks we sort them in
an ascending order on { pid, fd } pair.

Make this idea more formal by introducing an explicit function
doing this check and call it where appropriate (pipe.c master
selection is also simplified to fit new ... API).
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent a0560c42
...@@ -43,6 +43,12 @@ struct fdinfo_list_entry { ...@@ -43,6 +43,12 @@ struct fdinfo_list_entry {
FdinfoEntry *fe; FdinfoEntry *fe;
}; };
/* reports whether fd_a takes prio over fd_b */
static inline int fdinfo_rst_prio(struct fdinfo_list_entry *fd_a, struct fdinfo_list_entry *fd_b)
{
return (fd_a->pid < fd_b->pid) || ((fd_a->pid == fd_b->pid) && (fd_a->fe->fd < fd_b->fe->fd));
}
struct file_desc_ops { struct file_desc_ops {
unsigned int type; unsigned int type;
int (*open)(struct file_desc *d); int (*open)(struct file_desc *d);
......
...@@ -112,7 +112,6 @@ void mark_pipe_master(void) ...@@ -112,7 +112,6 @@ void mark_pipe_master(void)
while (1) { while (1) {
struct fdinfo_list_entry *fle; struct fdinfo_list_entry *fle;
struct pipe_info *pi, *pic, *p; struct pipe_info *pi, *pic, *p;
int fd, pid;
if (list_empty(&pipes)) if (list_empty(&pipes))
break; break;
...@@ -125,18 +124,15 @@ void mark_pipe_master(void) ...@@ -125,18 +124,15 @@ void mark_pipe_master(void)
fle = file_master(&pi->d); fle = file_master(&pi->d);
p = pi; p = pi;
fd = fle->fe->fd;
pid = fle->pid;
list_for_each_entry(pic, &pi->pipe_list, pipe_list) { list_for_each_entry(pic, &pi->pipe_list, pipe_list) {
list_move(&pic->list, &head); struct fdinfo_list_entry *f;
fle = file_master(&pic->d); list_move(&pic->list, &head);
if (fle->pid < pid || f = file_master(&pic->d);
(pid == fle->pid && fle->fe->fd < fd)) { if (fdinfo_rst_prio(f, fle)) {
p = pic; p = pic;
fd = fle->fe->fd; fle = f;
pid = fle->pid;
} }
show_saved_pipe_fds(pic); show_saved_pipe_fds(pic);
......
...@@ -762,9 +762,7 @@ int resolve_unix_peers(void) ...@@ -762,9 +762,7 @@ int resolve_unix_peers(void)
fle = file_master(&ui->d); fle = file_master(&ui->d);
fle_peer = file_master(&peer->d); fle_peer = file_master(&peer->d);
if ((fle->pid < fle_peer->pid) || if (fdinfo_rst_prio(fle, fle_peer)) {
(fle->pid == fle_peer->pid &&
fle->fe->fd < fle_peer->fe->fd)) {
ui->flags |= USK_PAIR_MASTER; ui->flags |= USK_PAIR_MASTER;
peer->flags |= USK_PAIR_SLAVE; peer->flags |= USK_PAIR_SLAVE;
} else { } else {
......
...@@ -670,8 +670,7 @@ static void tty_setup_orphan_slavery(void) ...@@ -670,8 +670,7 @@ static void tty_setup_orphan_slavery(void)
* waiting for each other. * waiting for each other.
*/ */
b = file_master(&peer->d); b = file_master(&peer->d);
if (a->pid > b->pid || if (fdinfo_rst_prio(b, a)) {
(a->pid == b->pid && a->fe->fd > b->fe->fd)) {
a = b; a = b;
m = peer; m = peer;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment