On Sat, Nov 19, 2011 at 8:33 AM, Jan Larres wrote: >> >> The problem is that the python interface in Vim is not thread safe. > > That's what I was worried about. I assume there's no easy way to fix > this then, other than using a higher sleep() value. But that just seems > wrong, especially since it can randomly lead to segfaults :(
I think it may be possible to fix this in the clang_complete plugin (https://github.com/Rip-Rip/clang_complete). In libclang.py, the getCurrentTranslationUnit() function starts with: def getCurrentTranslationUnit(args, update = False): currentFile = getCurrentFile() fileName = vim.current.buffer.name ... If 'currentFile' and 'fileName' are evaluated outside the thread instead of in the thread, then no calls to the Vim python interface are made within the thread anymore. This can be done by having the 'CompleteThread' class initialised with 'currentFile' and 'filename'. The following patch attempts to do that (not tested): =========================================================== --- libclang.orig.py 2011-11-19 12:11:16.000000000 +0100 +++ libclang.py 2011-11-19 12:19:51.000000000 +0100 @@ -18,10 +18,7 @@ file = "\n".join(vim.eval("getline(1, '$')")) return (vim.current.buffer.name, file) -def getCurrentTranslationUnit(args, update = False): - currentFile = getCurrentFile() - fileName = vim.current.buffer.name - +def getCurrentTranslationUnit(args, currentFile, fileName, update = False): if fileName in translationUnits: tu = translationUnits[fileName] if update: @@ -153,14 +150,14 @@ userOptionsGlobal = splitOptions(vim.eval("g:clang_user_options")) userOptionsLocal = splitOptions(vim.eval("b:clang_user_options")) args = userOptionsGlobal + userOptionsLocal - getCurrentTranslationUnit(args, update = True) + getCurrentTranslationUnit(args, getCurrentFile(), + vim.current.buffer.name, update = True) -def getCurrentCompletionResults(line, column, args): - tu = getCurrentTranslationUnit(args) - currentFile = getCurrentFile() +def getCurrentCompletionResults(line, column, args, currentFile, fileName): + tu = getCurrentTranslationUnit(args, currentFile, fileName) if debug: start = time.time() - cr = tu.codeComplete(vim.current.buffer.name, line, column, [currentFile], + cr = tu.codeComplete(fileName, line, column, [currentFile], complete_flags) if debug: elapsed = (time.time() - start) @@ -200,10 +197,12 @@ class CompleteThread(threading.Thread): lock = threading.Lock() - def __init__(self, line, column): + def __init__(self, line, column, currentFile, fileName): threading.Thread.__init__(self) self.line = line self.column = column + self.currentFile = currentFile + self.fileName = fileName self.result = None userOptionsGlobal = splitOptions(vim.eval("g:clang_user_options")) userOptionsLocal = splitOptions(vim.eval("b:clang_user_options")) @@ -219,10 +218,10 @@ # Otherwise we would get: E293: block was not locked # The user does not see any delay, as we just pause a background thread. time.sleep(0.1) - getCurrentTranslationUnit(self.args) + getCurrentTranslationUnit(self.args, self.currentFile, self.fileName) else: self.result = getCurrentCompletionResults(self.line, self.column, - self.args) + self.args, self.currentFile, self.fileName) except Exception: pass CompleteThread.lock.release() @@ -230,7 +229,7 @@ def WarmupCache(): global debug debug = int(vim.eval("g:clang_debug")) == 1 - t = CompleteThread(-1, -1) + t = CompleteThread(-1, -1, getCurrentFile(), vim.current.buffer.name) t.start() return @@ -242,7 +241,7 @@ line = int(vim.eval("line('.')")) column = int(vim.eval("b:col")) - t = CompleteThread(line, column) + t = CompleteThread(line, column, getCurrentFile(), vim.current.buffer.name) t.start() while t.isAlive(): t.join(0.01) =========================================================== -- Xavier Les Chemins de Lokoti: http://lokoti.alwaysdata.net -- You received this message from the "vim_dev" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php