package lsp

  1. Overview
  2. Docs
LSP protocol implementation in OCaml

Install

Dune Dependency

Authors

Maintainers

Sources

jsonrpc-1.6.0.tbz
sha256=35e8c7341f8eb1fa39fb0f0e0701a7ed90b9a0bb89ccf84b7ed997cd258cbec3
sha512=c96a7a3ca845ec193e9edc4a74804a22d6e37efc852b54575011879bd2105e0df021408632219f542ca3ad85b36b5c8b72f2b417204d154d5f0dd0839535afa5

doc/src/lsp.fiber_unix/barrier.ml.html

Source file barrier.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
open Import

type state =
  | Closed
  | Active of
      { r : Unix.file_descr
      ; w : Unix.file_descr
      ; await_mutex : Mutex.t
      ; mutex : Mutex.t
      ; buf : Bytes.t
      }

type t = state ref

let create () =
  let r, w = Unix.pipe () in
  ref
    (Active
       { r
       ; w
       ; mutex = Mutex.create ()
       ; await_mutex = Mutex.create ()
       ; buf = Bytes.create 1
       })

let close t =
  match !t with
  | Closed -> ()
  | Active { mutex; await_mutex = _; r; w; buf = _ } ->
    Mutex.lock mutex;
    (try Unix.close w with
    | Unix.Unix_error _ -> ());
    (try Unix.close r with
    | Unix.Unix_error _ -> ());
    t := Closed;
    Mutex.unlock mutex

let select fd timeout =
  match Unix.select [ fd ] [] [] timeout with
  | [], _, _ -> Ok `Empty
  | [ _ ], _, _ -> Ok `Ready_to_read
  | exception Unix.Unix_error (Unix.EBADF, _, _) -> Error `Closed
  | _ -> assert false

let rec drain_pipe fd buf read_once =
  match Unix.read fd buf 0 1 with
  | exception Unix.Unix_error (Unix.EBADF, _, _) ->
    Error (`Closed (`Read read_once))
  | 0 -> drain_pipe fd buf read_once
  | 1 -> (
    let read_once = true in
    match select fd 0. with
    | Ok `Empty -> Ok ()
    | Ok `Ready_to_read -> drain_pipe fd buf read_once
    | Error `Closed -> Error (`Closed (`Read read_once)))
  | _ -> assert false

let await ?(timeout = -1.) t =
  match !t with
  | Closed -> Error (`Closed (`Read false))
  | Active t ->
    with_mutex t.await_mutex ~f:(fun () ->
        match select t.r timeout with
        | Ok `Empty -> Error `Timeout
        | Ok `Ready_to_read -> drain_pipe t.r t.buf false
        | Error `Closed -> Error (`Closed (`Read false)))

let signal t =
  match !t with
  | Closed -> Error `Closed
  | Active { w; buf; _ } -> (
    match Unix.write w buf 0 1 with
    | exception Unix.Unix_error (Unix.EBADF, _, _) ->
      close t;
      Error `Closed
    | 1 -> Ok ()
    | _ -> assert false)
OCaml

Innovation. Community. Security.