Skip to content

Commit

Permalink
refactor open call to enable the OTP-8623 receive optimization
Browse files Browse the repository at this point in the history
Refactored the handling of the open call and the driver's handling of the
port_control call to enable the OTP-8623 receive optimization.
  • Loading branch information
vinoski committed Mar 24, 2013
1 parent a67e9b6 commit c34b18a
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 33 deletions.
24 changes: 9 additions & 15 deletions c_src/syslog_drv.c
Expand Up @@ -51,17 +51,6 @@ struct syslogdrv {

typedef struct syslogdrv syslogdrv_t;

static ErlDrvSSizeT encode_error(char* buf, char* error) {
int index = 0;
if (ei_encode_version(buf, &index) ||
ei_encode_tuple_header(buf, &index, 2) ||
ei_encode_atom(buf, &index, "error") ||
ei_encode_atom(buf, &index, error)) {
return (ErlDrvSSizeT)ERL_DRV_ERROR_GENERAL;
}
return index+1;
}

static ErlDrvData syslogdrv_start(ErlDrvPort port, char *buf)
{
syslogdrv_t* d = (syslogdrv_t*)driver_alloc(sizeof(syslogdrv_t));
Expand Down Expand Up @@ -110,7 +99,7 @@ static ErlDrvSSizeT syslogdrv_control(ErlDrvData handle, unsigned int command,
}

if (ei_decode_version(buf, &index, &version)) {
return encode_error(*rbuf, "badver");
return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG;
}
if (ei_decode_tuple_header(buf, &index, &arity) || arity != 4) {
return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG;
Expand All @@ -124,11 +113,13 @@ static ErlDrvSSizeT syslogdrv_control(ErlDrvData handle, unsigned int command,

syslogdrv_t* nd = (syslogdrv_t*)driver_alloc(sizeof(syslogdrv_t));
if (nd == NULL) {
return encode_error(*rbuf, "enomem");
errno = ENOMEM;
return (ErlDrvSSizeT)ERL_DRV_ERROR_ERRNO;
}
nd->ident = driver_alloc(size+1);
if (nd->ident == NULL) {
return encode_error(*rbuf, "enomem");
errno = ENOMEM;
return (ErlDrvSSizeT)ERL_DRV_ERROR_ERRNO;
}
if (ei_decode_string(buf, &index, nd->ident)) {
driver_free(nd->ident);
Expand All @@ -153,7 +144,10 @@ static ErlDrvSSizeT syslogdrv_control(ErlDrvData handle, unsigned int command,
}
ref = driver_alloc_binary(size);
if (ref == NULL) {
return encode_error(*rbuf, "enomem");
driver_free(nd->ident);
driver_free(nd);
errno = ENOMEM;
return (ErlDrvSSizeT)ERL_DRV_ERROR_ERRNO;
}
if (ei_decode_binary(buf, &index, ref->orig_bytes, &len)) {
driver_free_binary(ref);
Expand Down
35 changes: 17 additions & 18 deletions src/syslog.erl
Expand Up @@ -128,24 +128,23 @@ init([]) ->
end.

handle_call({open, Ident, Logopt, Facility}, {Pid,_}, #state{port = Port} = State) ->
Ref = make_ref(),
Args = term_to_binary({Ident, Logopt, Facility, term_to_binary(Ref)}),
Reply = try erlang:port_control(Port, ?SYSLOGDRV_OPEN, Args) of
<<>> ->
receive
{Ref, {ok, Log}=Result} ->
erlang:port_connect(Log, Pid),
unlink(Log),
Result;
{Ref, Result} ->
Result
end;
BinError ->
binary_to_term(BinError)
catch
_:Reason ->
{error, Reason}
end,
Reply =
try
Ref = make_ref(),
Args = term_to_binary({Ident, Logopt, Facility, term_to_binary(Ref)}),
erlang:port_control(Port, ?SYSLOGDRV_OPEN, Args),
receive
{Ref, {ok, Log}=Result} ->
erlang:port_connect(Log, Pid),
unlink(Log),
Result;
{Ref, Result} ->
Result
end
catch
_:Reason ->
{error, Reason}
end,
{reply, Reply, State};
handle_call(_Msg, _From, State) ->
{reply, ok, State}.
Expand Down

1 comment on commit c34b18a

@okeuday
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No messages are being sent from the port driver right now, right? Isn't this patch now invalid?

Please sign in to comment.