• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/ucode/tests/custom/06_lib_uloop/09_handle_reopened_path

  1 A script may close the descriptor of a handle without delete() and open the
  2 same path again, which yields the same number, device and inode. If another
  3 descriptor keeps the old file open, epoll still reports it to the old
  4 handle. Deleting the old handle must not remove the epoll entry of a handle
  5 that watches the new file.
  6 
  7 -- Testcase --
  8 {%
  9         import * as uloop from 'uloop';
 10         import * as fs from 'fs';
 11 
 12         uloop.init();
 13 
 14         let dir = fs.mkdtemp();
 15         let path = dir + '/fifo';
 16 
 17         system(['mkfifo', path]);
 18 
 19         function run() {
 20                 uloop.timer(50, () => uloop.end());
 21                 uloop.run();
 22         }
 23 
 24         let old_file = fs.open(path, 'r+');
 25         let old_fileno = old_file.fileno();
 26         let old_events = 0;
 27         let old_handle = uloop.handle(old_file, () => old_events++, uloop.ULOOP_READ);
 28 
 29         fs.dup2(old_fileno, 100);
 30         old_file.close();
 31 
 32         let file = fs.open(path, 'r+');
 33         let events = 0;
 34 
 35         uloop.handle(file, () => {
 36                 events++;
 37                 file.read(1);
 38         }, uloop.ULOOP_READ);
 39 
 40         printf("reused: %s\n", file.fileno() == old_fileno);
 41         printf("delete: %s\n", old_handle.delete());
 42 
 43         for (let i = 0; i < 2; i++) {
 44                 file.write('x');
 45                 file.flush();
 46                 run();
 47         }
 48 
 49         printf("old handle: %d, new handle: %d\n", old_events, events);
 50 
 51         fs.fdopen(100).close();
 52         fs.unlink(path);
 53         fs.rmdir(dir);
 54         uloop.done();
 55 %}
 56 -- End --
 57 
 58 -- Expect stdout --
 59 reused: true
 60 delete: true
 61 old handle: 0, new handle: 2
 62 -- End --
 63 
 64 
 65 When nothing watches the reopened file, the removal of the old handle fails.
 66 The old handle must then stay allocated for epoll, which still reports the
 67 old file to it.
 68 
 69 -- Testcase --
 70 {%
 71         import * as uloop from 'uloop';
 72         import * as fs from 'fs';
 73 
 74         uloop.init();
 75 
 76         let dir = fs.mkdtemp();
 77         let path = dir + '/fifo';
 78 
 79         system(['mkfifo', path]);
 80 
 81         let old_file = fs.open(path, 'r+');
 82         let old_fileno = old_file.fileno();
 83         let old_events = 0;
 84         let handle = uloop.handle(old_file, () => old_events++, uloop.ULOOP_READ);
 85 
 86         fs.dup2(old_fileno, 100);
 87         old_file.close();
 88 
 89         let file = fs.open(path, 'r+');
 90 
 91         printf("reused: %s\n", file.fileno() == old_fileno);
 92         printf("delete: %s\n", handle.delete());
 93 
 94         handle = null;
 95         gc();
 96 
 97         file.write('x');
 98         file.flush();
 99         uloop.timer(50, () => uloop.end());
100         uloop.run();
101 
102         printf("old handle: %d\n", old_events);
103 
104         fs.fdopen(100).close();
105         file.close();
106         fs.unlink(path);
107         fs.rmdir(dir);
108         uloop.done();
109 %}
110 -- End --
111 
112 -- Expect stdout --
113 reused: true
114 delete: true
115 old handle: 0
116 -- End --
117 
118 -- Platform --
119 Linux
120 -- End --
121 
122 
123 uloop.done() closes the epoll instance, so it unregisters all handles.
124 They are released like handles whose descriptor uloop removed, and a
125 later delete() does not touch a new registration of the same number.
126 
127 -- Testcase --
128 {%
129         import * as uloop from 'uloop';
130         import * as fs from 'fs';
131 
132         uloop.init();
133 
134         let fds = fs.pipe();
135         let base = gc('count');
136         let old_handle = uloop.handle(fds[0], () => null, uloop.ULOOP_READ);
137 
138         uloop.handle(fds[1], () => null, uloop.ULOOP_WRITE);
139         uloop.done();
140         gc();
141 
142         printf("dropped handle freed: %s\n", gc('count') - base == 2);
143 
144         uloop.init();
145 
146         let events = 0;
147 
148         uloop.handle(fds[0], () => {
149                 events++;
150                 fds[0].read(1);
151                 uloop.end();
152         }, uloop.ULOOP_READ);
153 
154         printf("delete: %s\n", old_handle.delete());
155         old_handle = null;
156 
157         fds[1].write('x');
158         fds[1].flush();
159 
160         let timer = uloop.timer(200, () => uloop.end());
161 
162         uloop.run();
163         timer.cancel();
164         timer = null;
165 
166         printf("events: %d\n", events);
167 
168         uloop.done();
169         gc();
170         printf("alive: %d\n", gc('count') - base);
171 %}
172 -- End --
173 
174 -- Expect stdout --
175 dropped handle freed: true
176 delete: true
177 events: 1
178 alive: 0
179 -- End --

This page was automatically generated by LXR 0.3.1.  •  OpenWrt