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