@@ -17,17 +17,24 @@ The classes responsible for autoloading functions and completions.
17
17
/* The time before we'll recheck an autoloaded file */
18
18
static const int kAutoloadStalenessInterval = 15 ;
19
19
20
- file_access_attempt_t access_file (const wcstring &path, int mode) {
20
+ file_access_attempt_t access_file (const wcstring &path, int mode)
21
+ {
21
22
// printf("Touch %ls\n", path.c_str());
22
23
file_access_attempt_t result = {0 };
23
24
struct stat statbuf;
24
- if (wstat (path, &statbuf)) {
25
+ if (wstat (path, &statbuf))
26
+ {
25
27
result.error = errno;
26
- } else {
28
+ }
29
+ else
30
+ {
27
31
result.mod_time = statbuf.st_mtime ;
28
- if (waccess (path, mode)) {
32
+ if (waccess (path, mode))
33
+ {
29
34
result.error = errno;
30
- } else {
35
+ }
36
+ else
37
+ {
31
38
result.accessible = true ;
32
39
}
33
40
}
@@ -39,21 +46,23 @@ file_access_attempt_t access_file(const wcstring &path, int mode) {
39
46
}
40
47
41
48
autoload_t ::autoload_t (const wcstring &env_var_name_var, const builtin_script_t * const scripts, size_t script_count) :
42
- lock (),
43
- env_var_name(env_var_name_var),
44
- builtin_scripts(scripts),
45
- builtin_script_count(script_count),
46
- last_path(),
47
- is_loading_set()
49
+ lock (),
50
+ env_var_name(env_var_name_var),
51
+ builtin_scripts(scripts),
52
+ builtin_script_count(script_count),
53
+ last_path(),
54
+ is_loading_set()
48
55
{
49
56
pthread_mutex_init (&lock, NULL );
50
57
}
51
58
52
- autoload_t ::~autoload_t () {
59
+ autoload_t ::~autoload_t ()
60
+ {
53
61
pthread_mutex_destroy (&lock);
54
62
}
55
63
56
- void autoload_t::node_was_evicted (autoload_function_t *node) {
64
+ void autoload_t::node_was_evicted (autoload_function_t *node)
65
+ {
57
66
// This should only ever happen on the main thread
58
67
ASSERT_IS_MAIN_THREAD ();
59
68
@@ -63,27 +72,27 @@ void autoload_t::node_was_evicted(autoload_function_t *node) {
63
72
delete node;
64
73
}
65
74
66
- int autoload_t::unload ( const wcstring &cmd )
75
+ int autoload_t::unload (const wcstring &cmd)
67
76
{
68
77
return this ->evict_node (cmd);
69
78
}
70
79
71
- int autoload_t::load ( const wcstring &cmd, bool reload )
80
+ int autoload_t::load (const wcstring &cmd, bool reload)
72
81
{
73
- int res;
74
- CHECK_BLOCK ( 0 );
82
+ int res;
83
+ CHECK_BLOCK (0 );
75
84
ASSERT_IS_MAIN_THREAD ();
76
85
77
- env_var_t path_var = env_get_string ( env_var_name );
86
+ env_var_t path_var = env_get_string (env_var_name);
78
87
79
88
/*
80
89
Do we know where to look?
81
90
*/
82
- if ( path_var.empty () )
91
+ if ( path_var.empty ())
83
92
return 0 ;
84
93
85
94
/* Check if the lookup path has changed. If so, drop all loaded files. path_var may only be inspected on the main thread. */
86
- if ( path_var != this ->last_path )
95
+ if ( path_var != this ->last_path )
87
96
{
88
97
this ->last_path = path_var;
89
98
scoped_lock locker (lock);
@@ -93,10 +102,10 @@ int autoload_t::load( const wcstring &cmd, bool reload )
93
102
/* * Warn and fail on infinite recursion. It's OK to do this because this function is only called on the main thread. */
94
103
if (this ->is_loading (cmd))
95
104
{
96
- debug ( 0 ,
97
- _ ( L" Could not autoload item '%ls', it is already being autoloaded. "
98
- L" This is a circular dependency in the autoloading scripts, please remove it." ),
99
- cmd.c_str () );
105
+ debug (0 ,
106
+ _ ( L" Could not autoload item '%ls', it is already being autoloaded. "
107
+ L" This is a circular dependency in the autoloading scripts, please remove it." ),
108
+ cmd.c_str ());
100
109
return 1 ;
101
110
}
102
111
@@ -105,48 +114,50 @@ int autoload_t::load( const wcstring &cmd, bool reload )
105
114
106
115
/* Get the list of paths from which we will try to load */
107
116
std::vector<wcstring> path_list;
108
- tokenize_variable_array ( path_var, path_list );
117
+ tokenize_variable_array (path_var, path_list);
109
118
110
- /* Try loading it */
111
- res = this ->locate_file_and_maybe_load_it ( cmd, true , reload, path_list );
119
+ /* Try loading it */
120
+ res = this ->locate_file_and_maybe_load_it (cmd, true , reload, path_list);
112
121
113
122
/* Clean up */
114
123
bool erased = !! is_loading_set.erase (cmd);
115
124
assert (erased);
116
125
117
- return res;
126
+ return res;
118
127
}
119
128
120
- bool autoload_t::can_load ( const wcstring &cmd, const env_vars_snapshot_t &vars )
129
+ bool autoload_t::can_load (const wcstring &cmd, const env_vars_snapshot_t &vars)
121
130
{
122
131
const env_var_t path_var = vars.get (env_var_name);
123
132
if (path_var.missing_or_empty ())
124
133
return false ;
125
134
126
135
std::vector<wcstring> path_list;
127
- tokenize_variable_array ( path_var, path_list );
128
- return this ->locate_file_and_maybe_load_it ( cmd, false , false , path_list );
136
+ tokenize_variable_array (path_var, path_list);
137
+ return this ->locate_file_and_maybe_load_it (cmd, false , false , path_list);
129
138
}
130
139
131
140
static bool script_name_precedes_script_name (const builtin_script_t &script1, const builtin_script_t &script2)
132
141
{
133
142
return wcscmp (script1.name , script2.name ) < 0 ;
134
143
}
135
144
136
- void autoload_t::unload_all (void ) {
145
+ void autoload_t::unload_all (void )
146
+ {
137
147
scoped_lock locker (lock);
138
148
this ->evict_all_nodes ();
139
149
}
140
150
141
151
/* * Check whether the given command is loaded. */
142
- bool autoload_t::has_tried_loading ( const wcstring &cmd )
152
+ bool autoload_t::has_tried_loading (const wcstring &cmd)
143
153
{
144
154
scoped_lock locker (lock);
145
155
autoload_function_t * func = this ->get_node (cmd);
146
156
return func != NULL ;
147
157
}
148
158
149
- static bool is_stale (const autoload_function_t *func) {
159
+ static bool is_stale (const autoload_function_t *func)
160
+ {
150
161
/* * Return whether this function is stale. Internalized functions can never be stale. */
151
162
return ! func->is_internalized && time (NULL ) - func->access .last_checked > kAutoloadStalenessInterval ;
152
163
}
@@ -155,11 +166,15 @@ autoload_function_t *autoload_t::get_autoloaded_function_with_creation(const wcs
155
166
{
156
167
ASSERT_IS_LOCKED (lock);
157
168
autoload_function_t *func = this ->get_node (cmd);
158
- if (! func) {
169
+ if (! func)
170
+ {
159
171
func = new autoload_function_t (cmd);
160
- if (allow_eviction) {
172
+ if (allow_eviction)
173
+ {
161
174
this ->add_node (func);
162
- } else {
175
+ }
176
+ else
177
+ {
163
178
this ->add_node_without_eviction (func);
164
179
}
165
180
}
@@ -178,11 +193,11 @@ autoload_function_t *autoload_t::get_autoloaded_function_with_creation(const wcs
178
193
179
194
Result: if really_load is true, returns whether the function was loaded. Otherwise returns whether the function existed.
180
195
*/
181
- bool autoload_t::locate_file_and_maybe_load_it ( const wcstring &cmd, bool really_load, bool reload, const wcstring_list_t &path_list )
196
+ bool autoload_t::locate_file_and_maybe_load_it (const wcstring &cmd, bool really_load, bool reload, const wcstring_list_t &path_list)
182
197
{
183
198
/* Note that we are NOT locked in this function! */
184
- size_t i;
185
- bool reloaded = 0 ;
199
+ size_t i;
200
+ bool reloaded = 0 ;
186
201
187
202
/* Try using a cached function. If we really want the function to be loaded, require that it be really loaded. If we're not reloading, allow stale functions. */
188
203
{
@@ -196,22 +211,30 @@ bool autoload_t::locate_file_and_maybe_load_it( const wcstring &cmd, bool really
196
211
197
212
/* Determine if we can use this cached function */
198
213
bool use_cached;
199
- if (! func) {
214
+ if (! func)
215
+ {
200
216
/* Can't use a function that doesn't exist */
201
217
use_cached = false ;
202
- } else if (really_load && ! func->is_placeholder && ! func->is_loaded ) {
218
+ }
219
+ else if (really_load && ! func->is_placeholder && ! func->is_loaded )
220
+ {
203
221
/* Can't use an unloaded function */
204
222
use_cached = false ;
205
- } else if ( ! allow_stale_functions && is_stale (func)) {
223
+ }
224
+ else if (! allow_stale_functions && is_stale (func))
225
+ {
206
226
/* Can't use a stale function */
207
227
use_cached = false ;
208
- } else {
228
+ }
229
+ else
230
+ {
209
231
/* I guess we can use it */
210
232
use_cached = true ;
211
233
}
212
234
213
235
/* If we can use this function, return whether we were able to access it */
214
- if (use_cached) {
236
+ if (use_cached)
237
+ {
215
238
return func->is_internalized || func->access .accessible ;
216
239
}
217
240
}
@@ -235,7 +258,8 @@ bool autoload_t::locate_file_and_maybe_load_it( const wcstring &cmd, bool really
235
258
matching_builtin_script = found;
236
259
}
237
260
}
238
- if (matching_builtin_script) {
261
+ if (matching_builtin_script)
262
+ {
239
263
has_script_source = true ;
240
264
script_source = str2wcstring (matching_builtin_script->def );
241
265
@@ -253,13 +277,14 @@ bool autoload_t::locate_file_and_maybe_load_it( const wcstring &cmd, bool really
253
277
if (! has_script_source)
254
278
{
255
279
/* Iterate over path searching for suitable completion files */
256
- for ( i=0 ; i<path_list.size (); i++ )
280
+ for ( i=0 ; i<path_list.size (); i++)
257
281
{
258
282
wcstring next = path_list.at (i);
259
283
wcstring path = next + L" /" + cmd + L" .fish" ;
260
284
261
285
const file_access_attempt_t access = access_file (path, R_OK);
262
- if (access .accessible ) {
286
+ if (access .accessible )
287
+ {
263
288
/* Found it! */
264
289
found_file = true ;
265
290
@@ -269,15 +294,17 @@ bool autoload_t::locate_file_and_maybe_load_it( const wcstring &cmd, bool really
269
294
270
295
/* Generate the source if we need to load it */
271
296
bool need_to_load_function = really_load && (func == NULL || func->access .mod_time != access .mod_time || ! func->is_loaded );
272
- if (need_to_load_function) {
297
+ if (need_to_load_function)
298
+ {
273
299
274
300
/* Generate the script source */
275
301
wcstring esc = escape_string (path, 1 );
276
302
script_source = L" . " + esc;
277
303
has_script_source = true ;
278
304
279
305
/* Remove any loaded command because we are going to reload it. Note that this will deadlock if command_removed calls back into us. */
280
- if (func && func->is_loaded ) {
306
+ if (func && func->is_loaded )
307
+ {
281
308
command_removed (cmd);
282
309
func->is_placeholder = false ;
283
310
}
@@ -287,7 +314,8 @@ bool autoload_t::locate_file_and_maybe_load_it( const wcstring &cmd, bool really
287
314
}
288
315
289
316
/* Create the function if we haven't yet. This does not load it. Do not trigger eviction unless we are actually loading, because we don't want to evict off of the main thread. */
290
- if (! func) {
317
+ if (! func)
318
+ {
291
319
func = get_autoloaded_function_with_creation (cmd, really_load);
292
320
}
293
321
@@ -306,17 +334,21 @@ bool autoload_t::locate_file_and_maybe_load_it( const wcstring &cmd, bool really
306
334
Later we only research if the current time is at least five seconds later.
307
335
This way, the files won't be searched over and over again.
308
336
*/
309
- if ( ! found_file && ! has_script_source )
337
+ if ( ! found_file && ! has_script_source)
310
338
{
311
339
scoped_lock locker (lock);
312
340
/* Generate a placeholder */
313
341
autoload_function_t *func = this ->get_node (cmd);
314
- if (! func) {
342
+ if (! func)
343
+ {
315
344
func = new autoload_function_t (cmd);
316
345
func->is_placeholder = true ;
317
- if (really_load) {
346
+ if (really_load)
347
+ {
318
348
this ->add_node (func);
319
- } else {
349
+ }
350
+ else
351
+ {
320
352
this ->add_node_without_eviction (func);
321
353
}
322
354
}
@@ -327,7 +359,7 @@ bool autoload_t::locate_file_and_maybe_load_it( const wcstring &cmd, bool really
327
359
/* If we have a script, either built-in or a file source, then run it */
328
360
if (really_load && has_script_source)
329
361
{
330
- if ( exec_subshell ( script_source) == -1 )
362
+ if ( exec_subshell (script_source) == -1 )
331
363
{
332
364
/*
333
365
Do nothing on failiure
@@ -336,9 +368,12 @@ bool autoload_t::locate_file_and_maybe_load_it( const wcstring &cmd, bool really
336
368
337
369
}
338
370
339
- if (really_load) {
371
+ if (really_load)
372
+ {
340
373
return reloaded;
341
- } else {
374
+ }
375
+ else
376
+ {
342
377
return found_file || has_script_source;
343
378
}
344
379
}
0 commit comments