2
2
//! environment, with associated path prefixes, which can be used to map
3
3
//! absolute paths to capabilities with relative paths.
4
4
5
- #ifdef _REENTRANT
6
- //#error "__wasilibc_register_preopened_fd doesn't yet support multiple threads"
7
- #endif
8
-
9
5
#include <assert.h>
10
6
#include <errno.h>
11
7
#include <fcntl.h>
12
8
#include <limits.h>
9
+ #include <lock.h>
13
10
#include <stdbool.h>
14
11
#include <stdlib.h>
15
12
#include <string.h>
@@ -32,6 +29,10 @@ static preopen *preopens;
32
29
static size_t num_preopens ;
33
30
static size_t preopen_capacity ;
34
31
32
+ /// Access to the the above preopen must be protected in the presence of
33
+ /// threads.
34
+ static volatile int lock [1 ];
35
+
35
36
#ifdef NDEBUG
36
37
#define assert_invariants () // assertions disabled
37
38
#else
@@ -55,13 +56,15 @@ static void assert_invariants(void) {
55
56
56
57
/// Allocate space for more preopens. Returns 0 on success and -1 on failure.
57
58
static int resize (void ) {
59
+ LOCK (lock );
58
60
size_t start_capacity = 4 ;
59
61
size_t old_capacity = preopen_capacity ;
60
62
size_t new_capacity = old_capacity == 0 ? start_capacity : old_capacity * 2 ;
61
63
62
64
preopen * old_preopens = preopens ;
63
65
preopen * new_preopens = calloc (sizeof (preopen ), new_capacity );
64
66
if (new_preopens == NULL )
67
+ UNLOCK (lock );
65
68
return -1 ;
66
69
67
70
memcpy (new_preopens , old_preopens , num_preopens * sizeof (preopen ));
@@ -70,6 +73,7 @@ static int resize(void) {
70
73
free (old_preopens );
71
74
72
75
assert_invariants ();
76
+ UNLOCK (lock );
73
77
return 0 ;
74
78
}
75
79
@@ -97,21 +101,26 @@ static const char *strip_prefixes(const char *path) {
97
101
///
98
102
/// This function takes ownership of `prefix`.
99
103
static int internal_register_preopened_fd (__wasi_fd_t fd , const char * relprefix ) {
104
+ LOCK (lock );
105
+
100
106
// Check preconditions.
101
107
assert_invariants ();
102
108
assert (fd != AT_FDCWD );
103
109
assert (fd != -1 );
104
110
assert (relprefix != NULL );
105
111
106
112
if (num_preopens == preopen_capacity && resize () != 0 )
113
+ UNLOCK (lock );
107
114
return -1 ;
108
115
109
116
char * prefix = strdup (strip_prefixes (relprefix ));
110
117
if (prefix == NULL )
118
+ UNLOCK (lock );
111
119
return -1 ;
112
120
preopens [num_preopens ++ ] = (preopen ) { prefix , fd , };
113
121
114
122
assert_invariants ();
123
+ UNLOCK (lock );
115
124
return 0 ;
116
125
}
117
126
@@ -166,6 +175,7 @@ int __wasilibc_find_abspath(const char *path,
166
175
// recently added preopens take precedence over less recently addded ones.
167
176
size_t match_len = 0 ;
168
177
int fd = -1 ;
178
+ LOCK (lock );
169
179
for (size_t i = num_preopens ; i > 0 ; -- i ) {
170
180
const preopen * pre = & preopens [i - 1 ];
171
181
const char * prefix = pre -> prefix ;
@@ -182,6 +192,7 @@ int __wasilibc_find_abspath(const char *path,
182
192
* abs_prefix = prefix ;
183
193
}
184
194
}
195
+ UNLOCK (lock );
185
196
186
197
if (fd == -1 ) {
187
198
errno = ENOENT ;
0 commit comments