10
10
#include "fd_table.h"
11
11
#include "wasi_types.h"
12
12
#include "uv_mapping.h"
13
+ #include "uvwasi_alloc.h"
13
14
14
15
15
16
#define UVWASI__RIGHTS_ALL (UVWASI_RIGHT_FD_DATASYNC | \
@@ -175,7 +176,8 @@ static uvwasi_errno_t uvwasi__get_type_and_rights(uv_file fd,
175
176
}
176
177
177
178
178
- static uvwasi_errno_t uvwasi__fd_table_insert (struct uvwasi_fd_table_t * table ,
179
+ static uvwasi_errno_t uvwasi__fd_table_insert (uvwasi_t * uvwasi ,
180
+ struct uvwasi_fd_table_t * table ,
179
181
uv_file fd ,
180
182
const char * mapped_path ,
181
183
const char * real_path ,
@@ -186,16 +188,22 @@ static uvwasi_errno_t uvwasi__fd_table_insert(struct uvwasi_fd_table_t* table,
186
188
struct uvwasi_fd_wrap_t * * wrap ) {
187
189
struct uvwasi_fd_wrap_t * entry ;
188
190
struct uvwasi_fd_wrap_t * new_fds ;
191
+ uvwasi_errno_t err ;
189
192
uint32_t new_size ;
190
193
int index ;
191
194
uint32_t i ;
195
+ int r ;
196
+
197
+ uv_rwlock_wrlock (& table -> rwlock );
192
198
193
199
/* Check that there is room for a new item. If there isn't, grow the table. */
194
200
if (table -> used >= table -> size ) {
195
201
new_size = table -> size * 2 ;
196
- new_fds = realloc (table -> fds , new_size * sizeof (* new_fds ));
197
- if (new_fds == NULL )
198
- return UVWASI_ENOMEM ;
202
+ new_fds = uvwasi__realloc (uvwasi , table -> fds , new_size * sizeof (* new_fds ));
203
+ if (new_fds == NULL ) {
204
+ err = UVWASI_ENOMEM ;
205
+ goto exit ;
206
+ }
199
207
200
208
for (i = table -> size ; i < new_size ; ++ i )
201
209
new_fds [i ].valid = 0 ;
@@ -214,11 +222,20 @@ static uvwasi_errno_t uvwasi__fd_table_insert(struct uvwasi_fd_table_t* table,
214
222
}
215
223
216
224
/* index should never be -1. */
217
- if (index == -1 )
218
- return UVWASI_ENOSPC ;
225
+ if (index == -1 ) {
226
+ err = UVWASI_ENOSPC ;
227
+ goto exit ;
228
+ }
219
229
}
220
230
221
231
entry = & table -> fds [index ];
232
+
233
+ r = uv_mutex_init (& entry -> mutex );
234
+ if (r != 0 ) {
235
+ err = uvwasi__translate_uv_error (r );
236
+ goto exit ;
237
+ }
238
+
222
239
entry -> id = index ;
223
240
entry -> fd = fd ;
224
241
strcpy (entry -> path , mapped_path );
@@ -233,29 +250,43 @@ static uvwasi_errno_t uvwasi__fd_table_insert(struct uvwasi_fd_table_t* table,
233
250
if (wrap != NULL )
234
251
* wrap = entry ;
235
252
236
- return UVWASI_ESUCCESS ;
253
+ err = UVWASI_ESUCCESS ;
254
+ exit :
255
+ uv_rwlock_wrunlock (& table -> rwlock );
256
+ return err ;
237
257
}
238
258
239
259
240
- uvwasi_errno_t uvwasi_fd_table_init (struct uvwasi_fd_table_t * table ,
260
+ uvwasi_errno_t uvwasi_fd_table_init (uvwasi_t * uvwasi ,
261
+ struct uvwasi_fd_table_t * table ,
241
262
uint32_t init_size ) {
242
263
struct uvwasi_fd_wrap_t * wrap ;
243
264
uvwasi_filetype_t type ;
244
265
uvwasi_rights_t base ;
245
266
uvwasi_rights_t inheriting ;
246
267
uvwasi_errno_t err ;
247
268
uvwasi_fd_t i ;
269
+ int r ;
248
270
249
271
/* Require an initial size of at least three to store the stdio FDs. */
250
272
if (table == NULL || init_size < 3 )
251
273
return UVWASI_EINVAL ;
252
274
275
+ table -> fds = NULL ;
276
+ r = uv_rwlock_init (& table -> rwlock );
277
+ if (r != 0 )
278
+ return uvwasi__translate_uv_error (r );
279
+
253
280
table -> used = 0 ;
254
281
table -> size = init_size ;
255
- table -> fds = calloc (init_size , sizeof (struct uvwasi_fd_wrap_t ));
282
+ table -> fds = uvwasi__calloc (uvwasi ,
283
+ init_size ,
284
+ sizeof (struct uvwasi_fd_wrap_t ));
256
285
257
- if (table -> fds == NULL )
258
- return UVWASI_ENOMEM ;
286
+ if (table -> fds == NULL ) {
287
+ err = UVWASI_ENOMEM ;
288
+ goto error_exit ;
289
+ }
259
290
260
291
/* Create the stdio FDs. */
261
292
for (i = 0 ; i < 3 ; ++ i ) {
@@ -267,7 +298,8 @@ uvwasi_errno_t uvwasi_fd_table_init(struct uvwasi_fd_table_t* table,
267
298
if (err != UVWASI_ESUCCESS )
268
299
goto error_exit ;
269
300
270
- err = uvwasi__fd_table_insert (table ,
301
+ err = uvwasi__fd_table_insert (uvwasi ,
302
+ table ,
271
303
i ,
272
304
"" ,
273
305
"" ,
@@ -287,23 +319,25 @@ uvwasi_errno_t uvwasi_fd_table_init(struct uvwasi_fd_table_t* table,
287
319
288
320
return UVWASI_ESUCCESS ;
289
321
error_exit :
290
- uvwasi_fd_table_free (table );
322
+ uvwasi_fd_table_free (uvwasi , table );
291
323
return err ;
292
324
}
293
325
294
326
295
- void uvwasi_fd_table_free (struct uvwasi_fd_table_t * table ) {
327
+ void uvwasi_fd_table_free (uvwasi_t * uvwasi , struct uvwasi_fd_table_t * table ) {
296
328
if (table == NULL )
297
329
return ;
298
330
299
- free ( table -> fds );
331
+ uvwasi__free ( uvwasi , table -> fds );
300
332
table -> fds = NULL ;
301
333
table -> size = 0 ;
302
334
table -> used = 0 ;
335
+ uv_rwlock_destroy (& table -> rwlock );
303
336
}
304
337
305
338
306
- uvwasi_errno_t uvwasi_fd_table_insert_preopen (struct uvwasi_fd_table_t * table ,
339
+ uvwasi_errno_t uvwasi_fd_table_insert_preopen (uvwasi_t * uvwasi ,
340
+ struct uvwasi_fd_table_t * table ,
307
341
const uv_file fd ,
308
342
const char * path ,
309
343
const char * real_path ) {
@@ -322,7 +356,8 @@ uvwasi_errno_t uvwasi_fd_table_insert_preopen(struct uvwasi_fd_table_t* table,
322
356
if (type != UVWASI_FILETYPE_DIRECTORY )
323
357
return UVWASI_ENOTDIR ;
324
358
325
- err = uvwasi__fd_table_insert (table ,
359
+ err = uvwasi__fd_table_insert (uvwasi ,
360
+ table ,
326
361
fd ,
327
362
path ,
328
363
real_path ,
@@ -338,7 +373,8 @@ uvwasi_errno_t uvwasi_fd_table_insert_preopen(struct uvwasi_fd_table_t* table,
338
373
}
339
374
340
375
341
- uvwasi_errno_t uvwasi_fd_table_insert_fd (struct uvwasi_fd_table_t * table ,
376
+ uvwasi_errno_t uvwasi_fd_table_insert_fd (uvwasi_t * uvwasi ,
377
+ struct uvwasi_fd_table_t * table ,
342
378
const uv_file fd ,
343
379
const int flags ,
344
380
const char * path ,
@@ -358,7 +394,8 @@ uvwasi_errno_t uvwasi_fd_table_insert_fd(struct uvwasi_fd_table_t* table,
358
394
if (r != UVWASI_ESUCCESS )
359
395
return r ;
360
396
361
- r = uvwasi__fd_table_insert (table ,
397
+ r = uvwasi__fd_table_insert (uvwasi ,
398
+ table ,
362
399
fd ,
363
400
path ,
364
401
path ,
@@ -381,42 +418,68 @@ uvwasi_errno_t uvwasi_fd_table_get(const struct uvwasi_fd_table_t* table,
381
418
uvwasi_rights_t rights_base ,
382
419
uvwasi_rights_t rights_inheriting ) {
383
420
struct uvwasi_fd_wrap_t * entry ;
421
+ uvwasi_errno_t err ;
384
422
385
423
if (table == NULL || wrap == NULL )
386
424
return UVWASI_EINVAL ;
387
- if (id >= table -> size )
388
- return UVWASI_EBADF ;
425
+
426
+ uv_rwlock_rdlock ((uv_rwlock_t * )& table -> rwlock );
427
+
428
+ if (id >= table -> size ) {
429
+ err = UVWASI_EBADF ;
430
+ goto exit ;
431
+ }
389
432
390
433
entry = & table -> fds [id ];
391
434
392
- if (entry -> valid != 1 || entry -> id != id )
393
- return UVWASI_EBADF ;
435
+ if (entry -> valid != 1 || entry -> id != id ) {
436
+ err = UVWASI_EBADF ;
437
+ goto exit ;
438
+ }
394
439
395
440
/* Validate that the fd has the necessary rights. */
396
441
if ((~entry -> rights_base & rights_base ) != 0 ||
397
- (~entry -> rights_inheriting & rights_inheriting ) != 0 )
398
- return UVWASI_ENOTCAPABLE ;
442
+ (~entry -> rights_inheriting & rights_inheriting ) != 0 ) {
443
+ err = UVWASI_ENOTCAPABLE ;
444
+ goto exit ;
445
+ }
399
446
447
+ uv_mutex_lock (& entry -> mutex );
400
448
* wrap = entry ;
401
- return UVWASI_ESUCCESS ;
449
+ err = UVWASI_ESUCCESS ;
450
+ exit :
451
+ uv_rwlock_rdunlock ((uv_rwlock_t * )& table -> rwlock );
452
+ return err ;
402
453
}
403
454
404
455
405
456
uvwasi_errno_t uvwasi_fd_table_remove (struct uvwasi_fd_table_t * table ,
406
457
const uvwasi_fd_t id ) {
407
458
struct uvwasi_fd_wrap_t * entry ;
459
+ uvwasi_errno_t err ;
408
460
409
461
if (table == NULL )
410
462
return UVWASI_EINVAL ;
411
- if (id >= table -> size )
412
- return UVWASI_EBADF ;
463
+
464
+ uv_rwlock_wrlock (& table -> rwlock );
465
+
466
+ if (id >= table -> size ) {
467
+ err = UVWASI_EBADF ;
468
+ goto exit ;
469
+ }
413
470
414
471
entry = & table -> fds [id ];
415
472
416
- if (entry -> valid != 1 || entry -> id != id )
417
- return UVWASI_EBADF ;
473
+ if (entry -> valid != 1 || entry -> id != id ) {
474
+ err = UVWASI_EBADF ;
475
+ goto exit ;
476
+ }
418
477
478
+ uv_mutex_destroy (& entry -> mutex );
419
479
entry -> valid = 0 ;
420
480
table -> used -- ;
421
- return UVWASI_ESUCCESS ;
481
+ err = UVWASI_ESUCCESS ;
482
+ exit :
483
+ uv_rwlock_wrunlock (& table -> rwlock );
484
+ return err ;
422
485
}
0 commit comments