1010#include "fd_table.h"
1111#include "wasi_types.h"
1212#include "uv_mapping.h"
13+ #include "uvwasi_alloc.h"
1314
1415
1516#define UVWASI__RIGHTS_ALL (UVWASI_RIGHT_FD_DATASYNC | \
@@ -175,7 +176,8 @@ static uvwasi_errno_t uvwasi__get_type_and_rights(uv_file fd,
175176}
176177
177178
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 ,
179181 uv_file fd ,
180182 const char * mapped_path ,
181183 const char * real_path ,
@@ -186,16 +188,22 @@ static uvwasi_errno_t uvwasi__fd_table_insert(struct uvwasi_fd_table_t* table,
186188 struct uvwasi_fd_wrap_t * * wrap ) {
187189 struct uvwasi_fd_wrap_t * entry ;
188190 struct uvwasi_fd_wrap_t * new_fds ;
191+ uvwasi_errno_t err ;
189192 uint32_t new_size ;
190193 int index ;
191194 uint32_t i ;
195+ int r ;
196+
197+ uv_rwlock_wrlock (& table -> rwlock );
192198
193199 /* Check that there is room for a new item. If there isn't, grow the table. */
194200 if (table -> used >= table -> size ) {
195201 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+ }
199207
200208 for (i = table -> size ; i < new_size ; ++ i )
201209 new_fds [i ].valid = 0 ;
@@ -214,11 +222,20 @@ static uvwasi_errno_t uvwasi__fd_table_insert(struct uvwasi_fd_table_t* table,
214222 }
215223
216224 /* 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+ }
219229 }
220230
221231 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+
222239 entry -> id = index ;
223240 entry -> fd = fd ;
224241 strcpy (entry -> path , mapped_path );
@@ -233,29 +250,43 @@ static uvwasi_errno_t uvwasi__fd_table_insert(struct uvwasi_fd_table_t* table,
233250 if (wrap != NULL )
234251 * wrap = entry ;
235252
236- return UVWASI_ESUCCESS ;
253+ err = UVWASI_ESUCCESS ;
254+ exit :
255+ uv_rwlock_wrunlock (& table -> rwlock );
256+ return err ;
237257}
238258
239259
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 ,
241262 uint32_t init_size ) {
242263 struct uvwasi_fd_wrap_t * wrap ;
243264 uvwasi_filetype_t type ;
244265 uvwasi_rights_t base ;
245266 uvwasi_rights_t inheriting ;
246267 uvwasi_errno_t err ;
247268 uvwasi_fd_t i ;
269+ int r ;
248270
249271 /* Require an initial size of at least three to store the stdio FDs. */
250272 if (table == NULL || init_size < 3 )
251273 return UVWASI_EINVAL ;
252274
275+ table -> fds = NULL ;
276+ r = uv_rwlock_init (& table -> rwlock );
277+ if (r != 0 )
278+ return uvwasi__translate_uv_error (r );
279+
253280 table -> used = 0 ;
254281 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 ));
256285
257- if (table -> fds == NULL )
258- return UVWASI_ENOMEM ;
286+ if (table -> fds == NULL ) {
287+ err = UVWASI_ENOMEM ;
288+ goto error_exit ;
289+ }
259290
260291 /* Create the stdio FDs. */
261292 for (i = 0 ; i < 3 ; ++ i ) {
@@ -267,7 +298,8 @@ uvwasi_errno_t uvwasi_fd_table_init(struct uvwasi_fd_table_t* table,
267298 if (err != UVWASI_ESUCCESS )
268299 goto error_exit ;
269300
270- err = uvwasi__fd_table_insert (table ,
301+ err = uvwasi__fd_table_insert (uvwasi ,
302+ table ,
271303 i ,
272304 "" ,
273305 "" ,
@@ -287,23 +319,25 @@ uvwasi_errno_t uvwasi_fd_table_init(struct uvwasi_fd_table_t* table,
287319
288320 return UVWASI_ESUCCESS ;
289321error_exit :
290- uvwasi_fd_table_free (table );
322+ uvwasi_fd_table_free (uvwasi , table );
291323 return err ;
292324}
293325
294326
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 ) {
296328 if (table == NULL )
297329 return ;
298330
299- free ( table -> fds );
331+ uvwasi__free ( uvwasi , table -> fds );
300332 table -> fds = NULL ;
301333 table -> size = 0 ;
302334 table -> used = 0 ;
335+ uv_rwlock_destroy (& table -> rwlock );
303336}
304337
305338
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 ,
307341 const uv_file fd ,
308342 const char * path ,
309343 const char * real_path ) {
@@ -322,7 +356,8 @@ uvwasi_errno_t uvwasi_fd_table_insert_preopen(struct uvwasi_fd_table_t* table,
322356 if (type != UVWASI_FILETYPE_DIRECTORY )
323357 return UVWASI_ENOTDIR ;
324358
325- err = uvwasi__fd_table_insert (table ,
359+ err = uvwasi__fd_table_insert (uvwasi ,
360+ table ,
326361 fd ,
327362 path ,
328363 real_path ,
@@ -338,7 +373,8 @@ uvwasi_errno_t uvwasi_fd_table_insert_preopen(struct uvwasi_fd_table_t* table,
338373}
339374
340375
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 ,
342378 const uv_file fd ,
343379 const int flags ,
344380 const char * path ,
@@ -358,7 +394,8 @@ uvwasi_errno_t uvwasi_fd_table_insert_fd(struct uvwasi_fd_table_t* table,
358394 if (r != UVWASI_ESUCCESS )
359395 return r ;
360396
361- r = uvwasi__fd_table_insert (table ,
397+ r = uvwasi__fd_table_insert (uvwasi ,
398+ table ,
362399 fd ,
363400 path ,
364401 path ,
@@ -381,42 +418,68 @@ uvwasi_errno_t uvwasi_fd_table_get(const struct uvwasi_fd_table_t* table,
381418 uvwasi_rights_t rights_base ,
382419 uvwasi_rights_t rights_inheriting ) {
383420 struct uvwasi_fd_wrap_t * entry ;
421+ uvwasi_errno_t err ;
384422
385423 if (table == NULL || wrap == NULL )
386424 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+ }
389432
390433 entry = & table -> fds [id ];
391434
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+ }
394439
395440 /* Validate that the fd has the necessary rights. */
396441 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+ }
399446
447+ uv_mutex_lock (& entry -> mutex );
400448 * wrap = entry ;
401- return UVWASI_ESUCCESS ;
449+ err = UVWASI_ESUCCESS ;
450+ exit :
451+ uv_rwlock_rdunlock ((uv_rwlock_t * )& table -> rwlock );
452+ return err ;
402453}
403454
404455
405456uvwasi_errno_t uvwasi_fd_table_remove (struct uvwasi_fd_table_t * table ,
406457 const uvwasi_fd_t id ) {
407458 struct uvwasi_fd_wrap_t * entry ;
459+ uvwasi_errno_t err ;
408460
409461 if (table == NULL )
410462 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+ }
413470
414471 entry = & table -> fds [id ];
415472
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+ }
418477
478+ uv_mutex_destroy (& entry -> mutex );
419479 entry -> valid = 0 ;
420480 table -> used -- ;
421- return UVWASI_ESUCCESS ;
481+ err = UVWASI_ESUCCESS ;
482+ exit :
483+ uv_rwlock_wrunlock (& table -> rwlock );
484+ return err ;
422485}
0 commit comments