Skip to content

Unexpected double call of cleanup by Lin #9

Closed
@OlivierNicole

Description

@OlivierNicole

I used Lin to perform concurrent output operations on files. My init function opens a temporary file for writing and the cleanup functions closes and removes it:

module Out_channel_ops = struct

  type t = string * Out_channel.t (* Filename and corresponding channel *)

  type cmd = Flush | Close | Write of string

  let show_cmd =
    let open Printf in function
    | Flush -> "Flush"
    | Write s -> sprintf "Write %s" s
    | Close -> "Close"

  let gen_cmd =
    let open QCheck.Gen in
    frequency
      [3, return Flush;
       1, return Close;
       6, map (fun s -> Write s) string;
      ]

  type res = (unit, exn) result

  let show_res =
    let open Printf in function
    | Ok () -> sprintf "()"
    | Error e -> sprintf "exception %s" (Printexc.to_string e)

  let init () =
    let filename = Filename.temp_file "fuzz_stdlib" "" in
    filename, Out_channel.open_text filename

  let cleanup (filename, chan) =
    Out_channel.close chan;
    Sys.remove filename

  let run cmd (_,chan) =
    match cmd with
    | Flush ->
        begin try Out_channel.flush chan; Ok ()
        with e -> Error e
        end
    | Write s ->
        begin try Out_channel.output_string chan s; Ok ()
        with e -> Error e
        end
    | Close ->
        begin try Out_channel.close chan; Ok ()
        with e -> Error e
        end
end

module Out_channel_lin = Lin.Make (Out_channel_ops)

let () =
  QCheck_runner.run_tests_main
    [ Out_channel_lin.lin_test ~count:1000 ~name:"Out_channel" `Domain;
    ]

Sometimes the programs fails with the “No such file or directory” error, so I assume Sys.remove is called twice on the same file. This surprises me as I would have expected init and cleanup to be used in a linear fashion.

Quickly looking at the code of Lin nothing obvious stands out, so maybe my assumption is false and this is an issue with uniqueness of temporary files or something. Since I do not quite have the time to look at it in detail now, I'm writing this issue to keep track of it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions