Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

debug #187

Closed
wants to merge 4 commits into from
Closed

debug #187

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion c_src/pipe.c
Original file line number Diff line number Diff line change
Expand Up @@ -385,11 +385,12 @@ static bool cancel_select(ErlNifEnv *env, int *fd) {

static void fd_rt_dtor(ErlNifEnv *env, void *obj) {
debug("fd_rt_dtor called");
int *fd = (int *)obj;
close_fd(fd);
}

static void fd_rt_stop(ErlNifEnv *env, void *obj, int fd, int is_direct_call) {
debug("fd_rt_stop called %d", fd);
close_fd(&fd);
}

static void fd_rt_down(ErlNifEnv *env, void *obj, ErlNifPid *pid,
Expand Down
66 changes: 66 additions & 0 deletions c_src/vips_foreign.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,72 @@ ERL_NIF_TERM nif_foreign_find_save(ErlNifEnv *env, int argc,
return ret;
}

ERL_NIF_TERM nif_foreign_find_load_source(ErlNifEnv *env, int argc,
const ERL_NIF_TERM argv[]) {
ASSERT_ARGC(argc, 1);

ErlNifTime start;
ERL_NIF_TERM ret;
VipsSource *source;
const char *name;

start = enif_monotonic_time(ERL_NIF_USEC);

if (!erl_term_to_g_object(env, argv[0], (GObject **)&source)) {
ret = make_error(env, "Failed to get VipsSource");
goto exit;
}

name = vips_foreign_find_load_source(source);

if (!name) {
error("Failed to find the loader for the source. error: %s",
vips_error_buffer());
vips_error_clear();
ret = make_error(env, "Failed to find loader for the source");
goto exit;
}

ret = make_ok(env, make_binary(env, name));

exit:
notify_consumed_timeslice(env, start, enif_monotonic_time(ERL_NIF_USEC));
return ret;
}

ERL_NIF_TERM nif_foreign_find_save_target(ErlNifEnv *env, int argc,
const ERL_NIF_TERM argv[]) {
ASSERT_ARGC(argc, 1);

ErlNifTime start;
ERL_NIF_TERM ret;
char suffix[VIPS_PATH_MAX];
const char *name;

start = enif_monotonic_time(ERL_NIF_USEC);

if (!get_binary(env, argv[0], suffix, VIPS_PATH_MAX)) {
ret = make_error(env, "Failed to get suffix");
goto exit;
}

name = vips_foreign_find_save_target(suffix);

if (!name) {
error("Failed to find saver for the target. error: %s",
vips_error_buffer());
vips_error_clear();
ret = make_error(env, "Failed to find saver for the target");
goto exit;
}

ret = make_ok(env, make_binary(env, name));

exit:
notify_consumed_timeslice(env, start, enif_monotonic_time(ERL_NIF_USEC));
return ret;
}

ERL_NIF_TERM nif_foreign_get_suffixes(ErlNifEnv *env, int argc,
const ERL_NIF_TERM argv[]) {
ASSERT_ARGC(argc, 0);
Expand Down
6 changes: 6 additions & 0 deletions c_src/vips_foreign.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ ERL_NIF_TERM nif_foreign_find_load(ErlNifEnv *env, int argc,
ERL_NIF_TERM nif_foreign_find_save(ErlNifEnv *env, int argc,
const ERL_NIF_TERM argv[]);

ERL_NIF_TERM nif_foreign_find_load_source(ErlNifEnv *env, int argc,
const ERL_NIF_TERM argv[]);

ERL_NIF_TERM nif_foreign_find_save_target(ErlNifEnv *env, int argc,
const ERL_NIF_TERM argv[]);

ERL_NIF_TERM nif_foreign_get_suffixes(ErlNifEnv *env, int argc,
const ERL_NIF_TERM argv[]);

Expand Down
6 changes: 5 additions & 1 deletion c_src/vix.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,14 @@ static ErlNifFunc nif_funcs[] = {
0},

/* VipsForeign */
{"nif_foreign_find_load", 1, nif_foreign_find_load, 0},
{"nif_foreign_find_load", 1, nif_foreign_find_load,
ERL_NIF_DIRTY_JOB_IO_BOUND}, // it might read bytes form the file
{"nif_foreign_find_save", 1, nif_foreign_find_save, 0},
{"nif_foreign_find_load_buffer", 1, nif_foreign_find_load_buffer, 0},
{"nif_foreign_find_save_buffer", 1, nif_foreign_find_save_buffer, 0},
{"nif_foreign_find_load_source", 1, nif_foreign_find_load_source,
ERL_NIF_DIRTY_JOB_IO_BOUND}, // it might read bytes from source
{"nif_foreign_find_save_target", 1, nif_foreign_find_save_target, 0},
{"nif_foreign_get_suffixes", 0, nif_foreign_get_suffixes, 0},
{"nif_foreign_get_loader_suffixes", 0, nif_foreign_get_loader_suffixes, 0},

Expand Down
6 changes: 6 additions & 0 deletions lib/vix/nif.ex
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,12 @@ defmodule Vix.Nif do
def nif_foreign_find_save(_filename),
do: :erlang.nif_error(:nif_library_not_loaded)

def nif_foreign_find_load_source(_source),
do: :erlang.nif_error(:nif_library_not_loaded)

def nif_foreign_find_save_target(_suffix),
do: :erlang.nif_error(:nif_library_not_loaded)

def nif_foreign_get_suffixes,
do: :erlang.nif_error(:nif_library_not_loaded)

Expand Down
9 changes: 8 additions & 1 deletion lib/vix/source_pipe.ex
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ defmodule Vix.SourcePipe do
defstruct bin: [], client_pid: nil
end

@spec new() :: {pid, Vix.Vips.Source.t()}
def new do
{:ok, pipe} = GenServer.start_link(__MODULE__, nil)
source = GenServer.call(pipe, :source, :infinity)
Expand All @@ -37,7 +38,13 @@ defmodule Vix.SourcePipe do
def handle_continue(nil, _) do
case Nif.nif_source_new() do
{:ok, {fd, source}} ->
{:noreply, %SourcePipe{fd: fd, pending: %Pending{}, source: source}}
source_pipe = %SourcePipe{
fd: fd,
pending: %Pending{},
source: %Vix.Vips.Source{ref: source}
}

{:noreply, source_pipe}

{:error, reason} ->
{:stop, reason, nil}
Expand Down
33 changes: 24 additions & 9 deletions lib/vix/target_pipe.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,20 @@ defmodule Vix.TargetPipe do

@moduledoc false

@type t() :: struct

defstruct [:fd, :pending, :task_result, :task_pid]

defmodule Pending do
@moduledoc false
defstruct size: nil, client_pid: nil
defstruct size: nil, client_pid: nil, opts: []
end

@default_buffer_size 65_535

def new(vips_image, suffix) do
GenServer.start_link(__MODULE__, %{image: vips_image, suffix: suffix})
@spec new(Vix.Vips.Image.t(), String.t(), keyword) :: GenServer.on_start()
def new(image, suffix, opts) do
GenServer.start_link(__MODULE__, %{image: image, suffix: suffix, opts: opts})
end

def read(process, max_size \\ @default_buffer_size)
Expand All @@ -31,15 +34,15 @@ defmodule Vix.TargetPipe do

# Server

def init(%{image: image, suffix: suffix}) do
def init(%{image: image, suffix: suffix, opts: opts}) do
Process.flag(:trap_exit, true)
{:ok, nil, {:continue, %{image: image, suffix: suffix}}}
{:ok, nil, {:continue, %{image: image, suffix: suffix, opts: opts}}}
end

def handle_continue(%{image: image, suffix: suffix}, _) do
def handle_continue(%{image: image, suffix: suffix, opts: opts}, _) do
case Nif.nif_target_new() do
{:ok, {fd, target}} ->
pid = start_task(image, target, suffix)
pid = start_task(image, %Vix.Vips.Target{ref: target}, suffix, opts)
{:noreply, %TargetPipe{fd: fd, task_pid: pid, pending: %Pending{}}}

{:error, reason} ->
Expand Down Expand Up @@ -98,9 +101,21 @@ defmodule Vix.TargetPipe do
{:noreply, state}
end

defp start_task(image, target, suffix) do
@spec start_task(Vix.Vips.Image.t(), Vix.Vips.Target.t(), String.t(), keyword) :: pid
defp start_task(%Vix.Vips.Image{} = image, target, suffix, []) do
spawn_link(fn ->
result = Nif.nif_image_to_target(image, target, suffix)
result = Nif.nif_image_to_target(image.ref, target.ref, suffix)
Process.exit(self(), result)
end)
end

defp start_task(image, target, suffix, opts) do
spawn_link(fn ->
result =
with {:ok, saver} <- Vix.Vips.Foreign.find_save_target(suffix) do
Vix.Vips.Operation.Helper.operation_call(saver, [image, target], opts)
end

Process.exit(self(), result)
end)
end
Expand Down
25 changes: 24 additions & 1 deletion lib/vix/vips/foreign.ex
Original file line number Diff line number Diff line change
@@ -1,23 +1,46 @@
defmodule Vix.Vips.Foreign do
alias Vix.Nif
@moduledoc false

alias Vix.Nif

@type operation_name :: String.t()

@spec find_load_buffer(binary) :: {:ok, operation_name} | {:error, String.t()}
def find_load_buffer(bin) do
Nif.nif_foreign_find_load_buffer(bin)
end

@spec find_save_buffer(String.t()) :: {:ok, operation_name} | {:error, String.t()}
def find_save_buffer(suffix) do
Nif.nif_foreign_find_save_buffer(suffix)
end

@doc """
Returns Vips operation name which can load the passed file
"""
@spec find_load(String.t()) :: {:ok, operation_name} | {:error, String.t()}
def find_load(filename) do
Nif.nif_foreign_find_load(filename)
end

@doc """
Returns Vips operation name which can save an image to passed format
"""
@spec find_save(String.t()) :: {:ok, operation_name} | {:error, String.t()}
def find_save(filename) do
Nif.nif_foreign_find_save(filename)
end

@spec find_load_source(Vix.Vips.Source.t()) :: {:ok, operation_name} | {:error, String.t()}
def find_load_source(%Vix.Vips.Source{ref: vips_source}) do
Nif.nif_foreign_find_load_source(vips_source)
end

@spec find_save_target(String.t()) :: {:ok, operation_name} | {:error, String.t()}
def find_save_target(suffix) do
Nif.nif_foreign_find_save_target(suffix)
end

def get_suffixes do
with {:ok, suffixes} <- Nif.nif_foreign_get_suffixes() do
{:ok, Enum.uniq(suffixes)}
Expand Down
Loading
Loading