Skip to content

Commit 3c8482a

Browse files
committed
wrap traversal operations in safe_fixtable
OTP docs are not clear if this is needed for selects and deletes used here it's better to be slower but safer
1 parent 18e8d52 commit 3c8482a

File tree

1 file changed

+52
-18
lines changed
  • apps/language_server/lib/language_server

1 file changed

+52
-18
lines changed

apps/language_server/lib/language_server/tracer.ex

Lines changed: 52 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,9 @@ defmodule ElixirLS.LanguageServer.Tracer do
156156

157157
defp maybe_close_tables(%{project_dir: nil}), do: :ok
158158

159-
defp maybe_close_tables(%{project_dir: project_dir}) do
159+
defp maybe_close_tables(_state) do
160160
for table <- @tables do
161-
close_table(table, project_dir)
161+
close_table(table)
162162
end
163163

164164
:ok
@@ -227,8 +227,7 @@ defmodule ElixirLS.LanguageServer.Tracer do
227227
end
228228
end
229229

230-
def close_table(table, project_dir) do
231-
path = dets_path(project_dir, table)
230+
def close_table(table) do
232231
table_name = table_name(table)
233232
sync(table_name)
234233

@@ -251,14 +250,28 @@ defmodule ElixirLS.LanguageServer.Tracer do
251250
ms = modules_by_file_matchspec(file, :"$_")
252251
# ms = :ets.fun2ms(fn {_, map} when :erlang.map_get(:file, map) == file -> map end)
253252

254-
:ets.select(table_name(:modules), ms)
253+
table = table_name(:modules)
254+
:ets.safe_fixtable(table, true)
255+
256+
try do
257+
:ets.select(table, ms)
258+
after
259+
:ets.safe_fixtable(table, false)
260+
end
255261
end
256262

257263
def delete_modules_by_file(file) do
258264
ms = modules_by_file_matchspec(file, true)
259265
# ms = :ets.fun2ms(fn {_, map} when :erlang.map_get(:file, map) == file -> true end)
260266

261-
:ets.select_delete(table_name(:modules), ms)
267+
table = table_name(:modules)
268+
:ets.safe_fixtable(table, true)
269+
270+
try do
271+
:ets.select_delete(table, ms)
272+
after
273+
:ets.safe_fixtable(table, false)
274+
end
262275
end
263276

264277
def trace(:start, %Macro.Env{} = env) do
@@ -363,16 +376,23 @@ defmodule ElixirLS.LanguageServer.Tracer do
363376

364377
def get_trace do
365378
# TODO get by callee
366-
:ets.tab2list(table_name(:calls))
367-
|> Enum.map(fn {{callee, file, line, column}, _} ->
368-
%{
369-
callee: callee,
370-
file: file,
371-
line: line,
372-
column: column
373-
}
374-
end)
375-
|> Enum.group_by(fn %{callee: callee} -> callee end)
379+
table = table_name(:calls)
380+
:ets.safe_fixtable(table, true)
381+
382+
try do
383+
:ets.tab2list(table)
384+
|> Enum.map(fn {{callee, file, line, column}, _} ->
385+
%{
386+
callee: callee,
387+
file: file,
388+
line: line,
389+
column: column
390+
}
391+
end)
392+
|> Enum.group_by(fn %{callee: callee} -> callee end)
393+
after
394+
:ets.safe_fixtable(table, false)
395+
end
376396
end
377397

378398
defp sync(table_name) do
@@ -405,13 +425,27 @@ defmodule ElixirLS.LanguageServer.Tracer do
405425
def get_calls_by_file(file) do
406426
ms = calls_by_file_matchspec(file, :"$_")
407427

408-
:ets.select(table_name(:calls), ms)
428+
table = table_name(:calls)
429+
:ets.safe_fixtable(table, true)
430+
431+
try do
432+
:ets.select(table, ms)
433+
after
434+
:ets.safe_fixtable(table, false)
435+
end
409436
end
410437

411438
def delete_calls_by_file(file) do
412439
ms = calls_by_file_matchspec(file, true)
413440

414-
:ets.select_delete(table_name(:calls), ms)
441+
table = table_name(:calls)
442+
:ets.safe_fixtable(table, true)
443+
444+
try do
445+
:ets.select_delete(table, ms)
446+
after
447+
:ets.safe_fixtable(table, false)
448+
end
415449
end
416450

417451
defp manifest_path(project_dir) do

0 commit comments

Comments
 (0)