forked from woai3c/MIT6.828
-
Notifications
You must be signed in to change notification settings - Fork 0
/
testpiperace2.c
69 lines (65 loc) · 1.83 KB
/
testpiperace2.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <inc/lib.h>
void
umain(int argc, char **argv)
{
int p[2], r, i;
struct Fd *fd;
const volatile struct Env *kid;
cprintf("testing for pipeisclosed race...\n");
if ((r = pipe(p)) < 0)
panic("pipe: %e", r);
if ((r = fork()) < 0)
panic("fork: %e", r);
if (r == 0) {
// child just dups and closes repeatedly,
// yielding so the parent can see
// the fd state between the two.
close(p[1]);
for (i = 0; i < 200; i++) {
if (i % 10 == 0)
cprintf("%d.", i);
// dup, then close. yield so that other guy will
// see us while we're between them.
dup(p[0], 10);
sys_yield();
close(10);
sys_yield();
}
exit();
}
// We hold both p[0] and p[1] open, so pipeisclosed should
// never return false.
//
// Now the ref count for p[0] will toggle between 2 and 3
// as the child dups and closes it.
// The ref count for p[1] is 1.
// Thus the ref count for the underlying pipe structure
// will toggle between 3 and 4.
//
// If pipeisclosed checks pageref(p[0]) and gets 3, and
// then the child closes, and then pipeisclosed checks
// pageref(pipe structure) and gets 3, then it will return true
// when it shouldn't.
//
// If pipeisclosed checks pageref(pipe structure) and gets 3,
// and then the child dups, and then pipeisclosed checks
// pageref(p[0]) and gets 3, then it will return true when
// it shouldn't.
//
// So either way, pipeisclosed is going give a wrong answer.
//
kid = &envs[ENVX(r)];
while (kid->env_status == ENV_RUNNABLE)
if (pipeisclosed(p[0]) != 0) {
cprintf("\nRACE: pipe appears closed\n");
sys_env_destroy(r);
exit();
}
cprintf("child done with loop\n");
if (pipeisclosed(p[0]))
panic("somehow the other end of p[0] got closed!");
if ((r = fd_lookup(p[0], &fd)) < 0)
panic("cannot look up p[0]: %e", r);
(void) fd2data(fd);
cprintf("race didn't happen\n");
}