Removed
Link Here
|
1 |
--- erts/emulator/drivers/common/efile_drv.c.orig |
2 |
+++ erts/emulator/drivers/common/efile_drv.c |
3 |
@@ -311,6 +311,18 @@ |
4 |
unsigned flags; /* Original flags from FILE_OPEN. */ |
5 |
void (*invoke)(void *); |
6 |
struct t_data *d; |
7 |
+ /* |
8 |
+ * If an operation against a compressed file is being executed |
9 |
+ * by an async thread, ensure the stop callback doesn't close |
10 |
+ * the fd (gzFile) while the async thread doesn't finish using |
11 |
+ * the fd (gzFile) - otherwise it accesses a dangling pointer. |
12 |
+ * The following comp_op_* variables are used to coordinate the |
13 |
+ * driver stop callback with the ongoing async operation. |
14 |
+ */ |
15 |
+ int comp_op_in_progress; |
16 |
+ volatile int comp_op_done; |
17 |
+ erts_mtx_t comp_op_mtx; |
18 |
+ erts_cnd_t comp_op_cnd; |
19 |
void (*free)(void *); |
20 |
struct t_data *cq_head; /* Queue of incoming commands */ |
21 |
struct t_data *cq_tail; /* -""- */ |
22 |
@@ -426,6 +438,9 @@ |
23 |
struct t_data *next; |
24 |
int command; |
25 |
int level; |
26 |
+ int volatile *comp_op_done; |
27 |
+ erts_mtx_t *comp_op_mtx; |
28 |
+ erts_cnd_t *comp_op_cnd; |
29 |
void (*invoke)(void *); |
30 |
void (*free)(void *); |
31 |
int again; |
32 |
@@ -714,6 +729,14 @@ |
33 |
return d; |
34 |
} |
35 |
|
36 |
+static void signal_comp_op_done(struct t_data *d) { |
37 |
+ if (d->comp_op_done != NULL) { |
38 |
+ erts_mtx_lock(d->comp_op_mtx); |
39 |
+ *(d->comp_op_done) = 1; |
40 |
+ erts_cnd_signal(d->comp_op_cnd); |
41 |
+ erts_mtx_unlock(d->comp_op_mtx); |
42 |
+ } |
43 |
+} |
44 |
|
45 |
/********************************************************************* |
46 |
* Driver entry point -> init |
47 |
@@ -757,6 +780,8 @@ |
48 |
desc->key = (unsigned int) (UWord) port; |
49 |
desc->flags = 0; |
50 |
desc->invoke = NULL; |
51 |
+ desc->comp_op_in_progress = 0; |
52 |
+ desc->comp_op_done = 0; |
53 |
desc->d = NULL; |
54 |
desc->free = NULL; |
55 |
desc->cq_head = NULL; |
56 |
@@ -800,6 +825,7 @@ |
57 |
DTRACE_INVOKE_SETUP(FILE_CLOSE); |
58 |
d->again = 0; |
59 |
do_close(d->flags, d->fd); |
60 |
+ signal_comp_op_done(d); |
61 |
DTRACE_INVOKE_RETURN(FILE_CLOSE); |
62 |
} |
63 |
|
64 |
@@ -814,9 +840,20 @@ |
65 |
TRACE_C('p'); |
66 |
|
67 |
if (desc->fd != FILE_FD_INVALID) { |
68 |
+ if (desc->comp_op_in_progress) { |
69 |
+ erts_mtx_lock(&desc->comp_op_mtx); |
70 |
+ while (!desc->comp_op_done) { |
71 |
+ erts_cnd_wait(&desc->comp_op_cnd, &desc->comp_op_mtx); |
72 |
+ } |
73 |
+ erts_mtx_unlock(&desc->comp_op_mtx); |
74 |
+ } |
75 |
do_close(desc->flags, desc->fd); |
76 |
desc->fd = FILE_FD_INVALID; |
77 |
desc->flags = 0; |
78 |
+ if (sys_info.async_threads > 0 && (desc->flags & EFILE_COMPRESSED)) { |
79 |
+ erts_cnd_destroy(&desc->comp_op_cnd); |
80 |
+ erts_mtx_destroy(&desc->comp_op_mtx); |
81 |
+ } |
82 |
} |
83 |
if (desc->read_binp) { |
84 |
driver_free_binary(desc->read_binp); |
85 |
@@ -1032,6 +1069,7 @@ |
86 |
{ |
87 |
DTRACE_INVOKE_SETUP_BY_NAME(FILE_MKDIR); |
88 |
invoke_name(data, efile_mkdir); |
89 |
+ signal_comp_op_done((struct t_data *) data); |
90 |
DTRACE_INVOKE_RETURN(FILE_MKDIR); |
91 |
} |
92 |
|
93 |
@@ -1039,6 +1077,7 @@ |
94 |
{ |
95 |
DTRACE_INVOKE_SETUP_BY_NAME(FILE_RMDIR); |
96 |
invoke_name(data, efile_rmdir); |
97 |
+ signal_comp_op_done((struct t_data *) data); |
98 |
DTRACE_INVOKE_RETURN(FILE_RMDIR); |
99 |
} |
100 |
|
101 |
@@ -1046,6 +1085,7 @@ |
102 |
{ |
103 |
DTRACE_INVOKE_SETUP_BY_NAME(FILE_DELETE); |
104 |
invoke_name(data, efile_delete_file); |
105 |
+ signal_comp_op_done((struct t_data *) data); |
106 |
DTRACE_INVOKE_RETURN(FILE_DELETE); |
107 |
} |
108 |
|
109 |
@@ -1053,6 +1093,7 @@ |
110 |
{ |
111 |
DTRACE_INVOKE_SETUP_BY_NAME(FILE_CHDIR); |
112 |
invoke_name(data, efile_chdir); |
113 |
+ signal_comp_op_done((struct t_data *) data); |
114 |
DTRACE_INVOKE_RETURN(FILE_CHDIR); |
115 |
} |
116 |
|
117 |
@@ -1064,6 +1105,7 @@ |
118 |
|
119 |
d->again = 0; |
120 |
d->result_ok = efile_fdatasync(&d->errInfo, fd); |
121 |
+ signal_comp_op_done(d); |
122 |
DTRACE_INVOKE_RETURN(FILE_FDATASYNC); |
123 |
} |
124 |
|
125 |
@@ -1075,6 +1117,7 @@ |
126 |
|
127 |
d->again = 0; |
128 |
d->result_ok = efile_fsync(&d->errInfo, fd); |
129 |
+ signal_comp_op_done(d); |
130 |
DTRACE_INVOKE_RETURN(FILE_FSYNC); |
131 |
} |
132 |
|
133 |
@@ -1086,6 +1129,7 @@ |
134 |
|
135 |
d->again = 0; |
136 |
d->result_ok = efile_truncate_file(&d->errInfo, &fd, d->flags); |
137 |
+ signal_comp_op_done(d); |
138 |
DTRACE_INVOKE_RETURN(FILE_TRUNCATE); |
139 |
} |
140 |
|
141 |
@@ -1129,6 +1173,7 @@ |
142 |
} else { |
143 |
d->again = 0; |
144 |
} |
145 |
+ signal_comp_op_done(d); |
146 |
DTRACE_INVOKE_RETURN(FILE_READ); |
147 |
} |
148 |
|
149 |
@@ -1238,6 +1283,7 @@ |
150 |
break; |
151 |
} |
152 |
} while (local_loop); |
153 |
+ signal_comp_op_done(d); |
154 |
DTRACE_INVOKE_RETURN(FILE_READ_LINE); |
155 |
} |
156 |
|
157 |
@@ -1298,6 +1344,7 @@ |
158 |
done: |
159 |
d->again = 0; |
160 |
chop_done: |
161 |
+ signal_comp_op_done(d); |
162 |
DTRACE_INVOKE_RETURN(FILE_READ_FILE); |
163 |
} |
164 |
|
165 |
@@ -1363,6 +1410,7 @@ |
166 |
} |
167 |
d->again = 0; |
168 |
done: |
169 |
+ signal_comp_op_done(d); |
170 |
DTRACE_INVOKE_RETURN(FILE_PREADV); |
171 |
} |
172 |
|
173 |
@@ -1434,6 +1482,7 @@ |
174 |
done: |
175 |
d->result_ok = !0; |
176 |
d->again = 0; |
177 |
+ signal_comp_op_done(d); |
178 |
DTRACE_INVOKE_RETURN(FILE_IPREAD); |
179 |
} |
180 |
|
181 |
@@ -1531,6 +1580,7 @@ |
182 |
TRACE_F(("w%lu", (unsigned long)size)); |
183 |
|
184 |
} |
185 |
+ signal_comp_op_done(d); |
186 |
DTRACE_INVOKE_RETURN(FILE_WRITE); |
187 |
} |
188 |
|
189 |
@@ -1550,6 +1600,7 @@ |
190 |
d->again = 0; |
191 |
d->result_ok = efile_getdcwd(&d->errInfo,d->drive, d->b+1, |
192 |
RESBUFSIZE-1); |
193 |
+ signal_comp_op_done(d); |
194 |
DTRACE_INVOKE_RETURN(FILE_PWD); |
195 |
} |
196 |
|
197 |
@@ -1564,6 +1615,7 @@ |
198 |
RESBUFSIZE-1); |
199 |
if (d->result_ok != 0) |
200 |
FILENAME_COPY((char *) d->b + 1, resbuf+1); |
201 |
+ signal_comp_op_done(d); |
202 |
DTRACE_INVOKE_RETURN(FILE_READLINK); |
203 |
} |
204 |
|
205 |
@@ -1578,6 +1630,7 @@ |
206 |
RESBUFSIZE-1); |
207 |
if (d->result_ok != 0) |
208 |
FILENAME_COPY((char *) d->b + 1, resbuf+1); |
209 |
+ signal_comp_op_done(d); |
210 |
DTRACE_INVOKE_RETURN(FILE_ALTNAME); |
211 |
} |
212 |
|
213 |
@@ -1670,6 +1723,7 @@ |
214 |
} |
215 |
} |
216 |
done: |
217 |
+ signal_comp_op_done(d); |
218 |
EF_FREE(iov); /* Free our copy of the vector, nothing to restore */ |
219 |
DTRACE_INVOKE_RETURN(FILE_PWRITEV); |
220 |
} |
221 |
@@ -1695,6 +1749,7 @@ |
222 |
DTRACE3(efile_drv_int_entry, d->sched_i1, d->sched_i2, |
223 |
d->command == FILE_LSTAT ? FILE_LSTAT : FILE_FSTAT); |
224 |
gcc_optimizer_hack++; |
225 |
+ signal_comp_op_done(d); |
226 |
} |
227 |
|
228 |
static void invoke_link(void *data) |
229 |
@@ -1707,6 +1762,7 @@ |
230 |
d->again = 0; |
231 |
new_name = name+FILENAME_BYTELEN(name)+FILENAME_CHARSIZE; |
232 |
d->result_ok = efile_link(&d->errInfo, name, new_name); |
233 |
+ signal_comp_op_done(d); |
234 |
DTRACE_INVOKE_RETURN(FILE_LINK); |
235 |
} |
236 |
|
237 |
@@ -1720,6 +1776,7 @@ |
238 |
d->again = 0; |
239 |
new_name = name+FILENAME_BYTELEN(name)+FILENAME_CHARSIZE; |
240 |
d->result_ok = efile_symlink(&d->errInfo, name, new_name); |
241 |
+ signal_comp_op_done(d); |
242 |
DTRACE_INVOKE_RETURN(FILE_SYMLINK); |
243 |
} |
244 |
|
245 |
@@ -1733,6 +1790,7 @@ |
246 |
d->again = 0; |
247 |
new_name = name+FILENAME_BYTELEN(name)+FILENAME_CHARSIZE; |
248 |
d->result_ok = efile_rename(&d->errInfo, name, new_name); |
249 |
+ signal_comp_op_done(d); |
250 |
DTRACE_INVOKE_RETURN(FILE_RENAME); |
251 |
} |
252 |
|
253 |
@@ -1743,6 +1801,7 @@ |
254 |
|
255 |
d->again = 0; |
256 |
d->result_ok = efile_write_info(&d->errInfo, &d->info, d->b); |
257 |
+ signal_comp_op_done(d); |
258 |
DTRACE_INVOKE_RETURN(FILE_WRITE_INFO); |
259 |
} |
260 |
|
261 |
@@ -1775,6 +1834,7 @@ |
262 |
&d->c.lseek.location); |
263 |
} |
264 |
d->result_ok = status; |
265 |
+ signal_comp_op_done(d); |
266 |
DTRACE_INVOKE_RETURN(FILE_LSEEK); |
267 |
} |
268 |
|
269 |
@@ -1822,6 +1882,7 @@ |
270 |
} while(res); |
271 |
|
272 |
d->result_ok = (d->errInfo.posix_errno == 0); |
273 |
+ signal_comp_op_done(d); |
274 |
DTRACE_INVOKE_RETURN(FILE_READDIR); |
275 |
} |
276 |
|
277 |
@@ -1876,6 +1937,7 @@ |
278 |
|
279 |
d->again = 0; |
280 |
d->result_ok = efile_fadvise(&d->errInfo, fd, offset, length, advise); |
281 |
+ signal_comp_op_done(d); |
282 |
DTRACE_INVOKE_RETURN(FILE_FADVISE); |
283 |
} |
284 |
|
285 |
@@ -1901,11 +1963,14 @@ |
286 |
d->result_ok = 1; |
287 |
if (d->c.sendfile.nbytes != 0) |
288 |
d->c.sendfile.nbytes -= nbytes; |
289 |
+ } else if (nbytes == 0 && d->c.sendfile.nbytes == 0) { |
290 |
+ d->result_ok = 1; |
291 |
} else |
292 |
d->result_ok = 0; |
293 |
} else { |
294 |
d->result_ok = -1; |
295 |
} |
296 |
+ signal_comp_op_done(d); |
297 |
} |
298 |
|
299 |
static void free_sendfile(void *data) { |
300 |
@@ -2023,6 +2088,21 @@ |
301 |
return; |
302 |
TRACE_F(("x%i", (int) d->command)); |
303 |
d->again = sys_info.async_threads == 0; |
304 |
+ |
305 |
+ if ((desc->flags & EFILE_COMPRESSED) && (sys_info.async_threads > 0) && |
306 |
+ (desc->fd != FILE_FD_INVALID)) { |
307 |
+ |
308 |
+ desc->comp_op_in_progress = 1; |
309 |
+ desc->comp_op_done = 0; |
310 |
+ d->comp_op_done = &desc->comp_op_done; |
311 |
+ d->comp_op_mtx = &desc->comp_op_mtx; |
312 |
+ d->comp_op_cnd = &desc->comp_op_cnd; |
313 |
+ } else { |
314 |
+ d->comp_op_done = NULL; |
315 |
+ d->comp_op_mtx = NULL; |
316 |
+ d->comp_op_cnd = NULL; |
317 |
+ } |
318 |
+ |
319 |
DRIVER_ASYNC(d->level, desc, d->invoke, void_ptr=d, d->free); |
320 |
} |
321 |
|
322 |
@@ -2247,6 +2327,8 @@ |
323 |
return; |
324 |
} |
325 |
|
326 |
+ desc->comp_op_in_progress = 0; |
327 |
+ |
328 |
switch (d->command) |
329 |
{ |
330 |
case FILE_READ: |
331 |
@@ -2375,6 +2457,10 @@ |
332 |
} else { |
333 |
desc->fd = d->fd; |
334 |
desc->flags = d->flags; |
335 |
+ if (sys_info.async_threads > 0 && (desc->flags & EFILE_COMPRESSED)) { |
336 |
+ erts_mtx_init(&desc->comp_op_mtx, "efile_drv comp op mutex"); |
337 |
+ erts_cnd_init(&desc->comp_op_cnd); |
338 |
+ } |
339 |
reply_Uint(desc, d->fd); |
340 |
} |
341 |
free_data(data); |