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 ,
179181uv_file fd ,
180182const char * mapped_path ,
181183const char * real_path ,
@@ -186,16 +188,22 @@ static uvwasi_errno_t uvwasi__fd_table_insert(struct uvwasi_fd_table_t* table,
186188struct uvwasi_fd_wrap_t * * wrap ){
187189struct uvwasi_fd_wrap_t * entry ;
188190struct uvwasi_fd_wrap_t * new_fds ;
191+ uvwasi_errno_t err ;
189192uint32_t new_size ;
190193int index ;
191194uint32_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. */
194200if (table -> used >= table -> size ){
195201new_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
200208for (i = table -> size ; i < new_size ; ++ i )
201209new_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
221231entry = & 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+
222239entry -> id = index ;
223240entry -> fd = fd ;
224241strcpy (entry -> path , mapped_path );
@@ -233,29 +250,43 @@ static uvwasi_errno_t uvwasi__fd_table_insert(struct uvwasi_fd_table_t* table,
233250if (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 ,
241262uint32_t init_size ){
242263struct uvwasi_fd_wrap_t * wrap ;
243264uvwasi_filetype_t type ;
244265uvwasi_rights_t base ;
245266uvwasi_rights_t inheriting ;
246267uvwasi_errno_t err ;
247268uvwasi_fd_t i ;
269+ int r ;
248270
249271/* Require an initial size of at least three to store the stdio FDs. */
250272if (table == NULL || init_size < 3 )
251273return 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+
253280table -> used = 0 ;
254281table -> 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. */
261292for (i = 0 ; i < 3 ; ++ i ){
@@ -267,7 +298,8 @@ uvwasi_errno_t uvwasi_fd_table_init(struct uvwasi_fd_table_t* table,
267298if (err != UVWASI_ESUCCESS )
268299 goto error_exit ;
269300
270- err = uvwasi__fd_table_insert (table ,
301+ err = uvwasi__fd_table_insert (uvwasi ,
302+ table ,
271303i ,
272304"" ,
273305"" ,
@@ -287,23 +319,25 @@ uvwasi_errno_t uvwasi_fd_table_init(struct uvwasi_fd_table_t* table,
287319
288320return UVWASI_ESUCCESS ;
289321error_exit :
290- uvwasi_fd_table_free (table );
322+ uvwasi_fd_table_free (uvwasi , table );
291323return 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 ){
296328if (table == NULL )
297329return ;
298330
299- free ( table -> fds );
331+ uvwasi__free ( uvwasi , table -> fds );
300332table -> fds = NULL ;
301333table -> size = 0 ;
302334table -> 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 ,
307341const uv_file fd ,
308342const char * path ,
309343const char * real_path ){
@@ -322,7 +356,8 @@ uvwasi_errno_t uvwasi_fd_table_insert_preopen(struct uvwasi_fd_table_t* table,
322356if (type != UVWASI_FILETYPE_DIRECTORY )
323357return UVWASI_ENOTDIR ;
324358
325- err = uvwasi__fd_table_insert (table ,
359+ err = uvwasi__fd_table_insert (uvwasi ,
360+ table ,
326361fd ,
327362path ,
328363real_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 ,
342378const uv_file fd ,
343379const int flags ,
344380const char * path ,
@@ -358,7 +394,8 @@ uvwasi_errno_t uvwasi_fd_table_insert_fd(struct uvwasi_fd_table_t* table,
358394if (r != UVWASI_ESUCCESS )
359395return r ;
360396
361- r = uvwasi__fd_table_insert (table ,
397+ r = uvwasi__fd_table_insert (uvwasi ,
398+ table ,
362399fd ,
363400path ,
364401path ,
@@ -381,42 +418,68 @@ uvwasi_errno_t uvwasi_fd_table_get(const struct uvwasi_fd_table_t* table,
381418uvwasi_rights_t rights_base ,
382419uvwasi_rights_t rights_inheriting ){
383420struct uvwasi_fd_wrap_t * entry ;
421+ uvwasi_errno_t err ;
384422
385423if (table == NULL || wrap == NULL )
386424return 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
390433entry = & 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. */
396441if ((~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 ,
406457const uvwasi_fd_t id ){
407458struct uvwasi_fd_wrap_t * entry ;
459+ uvwasi_errno_t err ;
408460
409461if (table == NULL )
410462return 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
414471entry = & 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 );
419479entry -> valid = 0 ;
420480table -> used -- ;
421- return UVWASI_ESUCCESS ;
481+ err = UVWASI_ESUCCESS ;
482+ exit :
483+ uv_rwlock_wrunlock (& table -> rwlock );
484+ return err ;
422485}
0 commit comments