Mercurial > vim-gutentags
comparison plugin/autotags.vim @ 15:b557282af215
Fix race condition between the statusline and the lock file.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Tue, 29 Jul 2014 16:11:24 -0700 |
parents | b8f23bf7b20f |
children | c11616828595 |
comparison
equal
deleted
inserted
replaced
14:b8f23bf7b20f | 15:b557282af215 |
---|---|
203 if has('win32') | 203 if has('win32') |
204 let s:runner_exe = expand('<sfile>:h:h') . '\plat\win32\update_tags.cmd' | 204 let s:runner_exe = expand('<sfile>:h:h') . '\plat\win32\update_tags.cmd' |
205 endif | 205 endif |
206 | 206 |
207 let s:update_queue = [] | 207 let s:update_queue = [] |
208 let s:maybe_in_progress = [] | 208 let s:maybe_in_progress = {} |
209 | 209 |
210 " Get how to execute an external command depending on debug settings. | 210 " Get how to execute an external command depending on debug settings. |
211 function! s:get_execute_cmd() abort | 211 function! s:get_execute_cmd() abort |
212 if has('win32') | 212 if has('win32') |
213 let l:cmd = '!start ' | 213 let l:cmd = '!start ' |
317 let l:cmd .= ' > /dev/null 2>&1' | 317 let l:cmd .= ' > /dev/null 2>&1' |
318 endif | 318 endif |
319 endif | 319 endif |
320 let l:cmd .= s:get_execute_cmd_suffix() | 320 let l:cmd .= s:get_execute_cmd_suffix() |
321 | 321 |
322 " Run the background process. | |
323 call s:trace("Running: " . l:cmd) | 322 call s:trace("Running: " . l:cmd) |
324 call s:trace("In: " . l:work_dir) | 323 call s:trace("In: " . l:work_dir) |
325 if !g:autotags_fake | 324 if !g:autotags_fake |
326 " Flag this tags file as being in progress | 325 " Run the background process. |
327 call add(s:maybe_in_progress, fnamemodify(l:tags_file, ':p')) | |
328 | |
329 if !g:autotags_trace | 326 if !g:autotags_trace |
330 silent execute l:cmd | 327 silent execute l:cmd |
331 else | 328 else |
332 execute l:cmd | 329 execute l:cmd |
333 endif | 330 endif |
331 | |
332 " Flag this tags file as being in progress | |
333 let l:full_tags_file = fnamemodify(l:tags_file, ':p') | |
334 let s:maybe_in_progress[l:full_tags_file] = localtime() | |
334 else | 335 else |
335 call s:trace("(fake... not actually running)") | 336 call s:trace("(fake... not actually running)") |
336 endif | 337 endif |
337 call s:trace("") | 338 call s:trace("") |
338 finally | 339 finally |
407 echom "" | 408 echom "" |
408 endfunction | 409 endfunction |
409 | 410 |
410 function! autotags#inprogress() | 411 function! autotags#inprogress() |
411 echom "autotags: generations in progress:" | 412 echom "autotags: generations in progress:" |
412 for mip in s:maybe_in_progress | 413 for mip in keys(s:maybe_in_progress) |
413 echom mip | 414 echom mip |
414 endfor | 415 endfor |
415 echom "" | 416 echom "" |
416 endfunction | 417 endfunction |
417 | 418 |
426 " - args 1 and 2 are the prefix and suffix, respectively, of whatever output, | 427 " - args 1 and 2 are the prefix and suffix, respectively, of whatever output, |
427 " if any, is going to be produced. | 428 " if any, is going to be produced. |
428 " (defaults to empty strings) | 429 " (defaults to empty strings) |
429 " - arg 3 is the text to be shown if tags are currently being generated. | 430 " - arg 3 is the text to be shown if tags are currently being generated. |
430 " (defaults to 'TAGS') | 431 " (defaults to 'TAGS') |
431 " | 432 |
432 function! autotags#statusline(...) abort | 433 function! autotags#statusline(...) abort |
433 if !exists('b:autotags_file') | 434 if !exists('b:autotags_file') |
434 " This buffer doesn't have autotags. | 435 " This buffer doesn't have autotags. |
435 return '' | 436 return '' |
436 endif | 437 endif |
444 " To make this function as fast as possible, we first check whether the | 445 " To make this function as fast as possible, we first check whether the |
445 " current buffer's tags file is 'maybe' being generated. This provides a | 446 " current buffer's tags file is 'maybe' being generated. This provides a |
446 " nice and quick bail out for 99.9% of cases before we need to this the | 447 " nice and quick bail out for 99.9% of cases before we need to this the |
447 " file-system to check the lock file. | 448 " file-system to check the lock file. |
448 let l:abs_tag_file = fnamemodify(b:autotags_file, ':p') | 449 let l:abs_tag_file = fnamemodify(b:autotags_file, ':p') |
449 let l:found = index(s:maybe_in_progress, l:abs_tag_file) | 450 let l:timestamp = get(s:maybe_in_progress, l:abs_tag_file) |
450 if l:found < 0 | 451 if l:timestamp == 0 |
451 return '' | 452 return '' |
452 endif | 453 endif |
453 " It's maybe generating! Check if the lock file is still there. | 454 " It's maybe generating! Check if the lock file is still there... but |
454 if !filereadable(l:abs_tag_file . '.lock') | 455 " don't do it too soon after the script was originally launched, because |
455 call remove(s:maybe_in_progress, l:found) | 456 " there can be a race condition where we get here just before the script |
457 " had a chance to write the lock file. | |
458 if (localtime() - l:timestamp) > 1 && | |
459 \!filereadable(l:abs_tag_file . '.lock') | |
460 call remove(s:maybe_in_progress, l:abs_tag_file) | |
456 return '' | 461 return '' |
457 endif | 462 endif |
458 " It's still there! So probably `ctags` is still running... | 463 " It's still there! So probably `ctags` is still running... |
459 " (although there's a chance it crashed, or the script had a problem, and | 464 " (although there's a chance it crashed, or the script had a problem, and |
460 " the lock file has been left behind... we could try and run some | 465 " the lock file has been left behind... we could try and run some |