diff --git a/src/async_nif.hrl b/src/async_nif.hrl index 44b7a2a..d7b5bee 100644 --- a/src/async_nif.hrl +++ b/src/async_nif.hrl @@ -21,28 +21,26 @@ %% %% ------------------------------------------------------------------- --spec async_nif_enqueue(function(), [term()]) -> term() | {error, term()}. -async_nif_enqueue(F, A) -> - R = erlang:make_ref(), - case erlang:apply(F, [R|A]) of - {ok, enqueued} -> - receive - {R, {error, shutdown}=Error} -> - %% Work unit was queued, but not executed. - Error; - {R, {error, _Reason}=Error} -> - %% Work unit returned an error. - Error; - {R, Reply} -> - Reply - end; - {error, eagain} -> - %% Work unit was not queued, try again. - async_nif_enqueue(F, A); - %{error, enomem} -> - %{error, shutdown} -> - Other -> - Other - end. - --define(ASYNC_NIF_CALL(Fun, Args), async_nif_enqueue(Fun, Args)). +-define(ASYNC_NIF_CALL(Fun, Args), + F = fun(F, A, R, T) -> + case erlang:apply(F, [R|A]) of + {ok, enqueued} -> + receive + {R, {error, shutdown}=Error} -> + %% Work unit was queued, but not executed. + Error; + {R, {error, _Reason}=Error} -> + %% Work unit returned an error. + Error; + {R, Reply} -> + Reply + end; + {error, eagain} -> + SleepyTime = min(30, (T+1)*2), + timer:sleep(SleepyTime), + F(F, A, R, SleepyTime); + Other -> + Other + end + end, + F(Fun, Args, erlang:make_ref(), 1)).