<feed xmlns='http://www.w3.org/2005/Atom'>
<title>rneovim.git/src/nvim/msgpack_rpc, branch v0.2.1</title>
<subtitle>Neovim fork with Rahm's personal hacks.
</subtitle>
<link rel='alternate' type='text/html' href='https://git.josher.dev/cgit/rneovim.git/'/>
<entry>
<title>rpc: Don't delay notifications when request is pending (#6544)</title>
<updated>2017-10-29T02:06:53+00:00</updated>
<author>
<name>Björn Linse</name>
<email>bjorn.linse@gmail.com</email>
</author>
<published>2017-10-29T02:06:53+00:00</published>
<link rel='alternate' type='text/html' href='https://git.josher.dev/cgit/rneovim.git/commit/?id=2a3bcd1ff883429a3dd17e7ae5ddc1396abbad17'/>
<id>2a3bcd1ff883429a3dd17e7ae5ddc1396abbad17</id>
<content type='text'>
With the old behavior, if a GUI makes a blocking request that requires user
interaction (like nvim_input()), it would not get any screen updates.

The client, not nvim, should decide how to handle notifications during a
pending request. If an rplugin wants to avoid async calls while a sync call is
busy, it likely wants to avoid processing async calls while another async call
also is handled as well.

This may break the expectation of some existing rplugins. For compatibility,
remote/define.vim reimplements the old behavior. Clients can opt-out by
specifying `sync=urgent`.

- Legacy hosts should be updated to use `sync=urgent`. They could add a flag
  indicating which async methods are always safe to call and which must wait
  until the main loop returns.
- New hosts can expose the full asyncness, they don't need to offer both
  behaviors.

ref #6532
ref #1398 d83868fe9071af1b4866594eac12f7aa0fa71b53</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
With the old behavior, if a GUI makes a blocking request that requires user
interaction (like nvim_input()), it would not get any screen updates.

The client, not nvim, should decide how to handle notifications during a
pending request. If an rplugin wants to avoid async calls while a sync call is
busy, it likely wants to avoid processing async calls while another async call
also is handled as well.

This may break the expectation of some existing rplugins. For compatibility,
remote/define.vim reimplements the old behavior. Clients can opt-out by
specifying `sync=urgent`.

- Legacy hosts should be updated to use `sync=urgent`. They could add a flag
  indicating which async methods are always safe to call and which must wait
  until the main loop returns.
- New hosts can expose the full asyncness, they don't need to offer both
  behaviors.

ref #6532
ref #1398 d83868fe9071af1b4866594eac12f7aa0fa71b53</pre>
</div>
</content>
</entry>
<entry>
<title>doc: channel, eventloop</title>
<updated>2017-09-05T13:01:07+00:00</updated>
<author>
<name>Justin M. Keyes</name>
<email>justinkz@gmail.com</email>
</author>
<published>2017-09-02T17:51:49+00:00</published>
<link rel='alternate' type='text/html' href='https://git.josher.dev/cgit/rneovim.git/commit/?id=cdd9e868efdad1f1eb9febfabb5f8671e75b95b9'/>
<id>cdd9e868efdad1f1eb9febfabb5f8671e75b95b9</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>channel.c:call_set_error(): fix memory leak</title>
<updated>2017-08-20T23:04:28+00:00</updated>
<author>
<name>Justin M. Keyes</name>
<email>justinkz@gmail.com</email>
</author>
<published>2017-08-18T12:13:28+00:00</published>
<link rel='alternate' type='text/html' href='https://git.josher.dev/cgit/rneovim.git/commit/?id=0f442c328e33a0c742df9283c1944c077d202a77'/>
<id>0f442c328e33a0c742df9283c1944c077d202a77</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>rpc: close channel if stream was closed</title>
<updated>2017-08-20T23:04:28+00:00</updated>
<author>
<name>Justin M. Keyes</name>
<email>justinkz@gmail.com</email>
</author>
<published>2017-07-26T23:08:50+00:00</published>
<link rel='alternate' type='text/html' href='https://git.josher.dev/cgit/rneovim.git/commit/?id=af993da4351d579aa24de08d806c8c1b90813106'/>
<id>af993da4351d579aa24de08d806c8c1b90813106</id>
<content type='text'>
f_jobstop()/f_rpcstop() .. process_stop() .. process_close_in(proc)
closes the write-stream of a RPC channel. But there might be
a pending RPC notification on the queue, which may get processed just
before the channel is closed.

To handle that case, check the Stream.closed in
channel.c:receive_msgpack().

Before this change, the above scenario could trigger
this assert(!stream-&gt;closed) in wstream_write():

    0x00007f96e1cd3428 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:54
    0x00007f96e1cd502a in __GI_abort () at abort.c:89
    0x00007f96e1ccbbd7 in __assert_fail_base (fmt=&lt;optimized out&gt;, assertion=assertion@entry=0x768f9b "!stream-&gt;closed",
    file=file@entry=0x768f70 "../src/nvim/event/wstream.c", line=line@entry=77,
    function=function@entry=0x768fb0 &lt;__PRETTY_FUNCTION__.13735&gt; "wstream_write") at assert.c:92
    0x00007f96e1ccbc82 in __GI___assert_fail (assertion=0x768f9b "!stream-&gt;closed", file=0x768f70 "../src/nvim/event/wstream.c", line=77,
    function=0x768fb0 &lt;__PRETTY_FUNCTION__.13735&gt; "wstream_write") at assert.c:101
    0x00000000004d2c1f in wstream_write (stream=0x7f96e0a35078, buffer=0x7f96e09f9b40) at ../src/nvim/event/wstream.c:77
    0x00000000005857b2 in channel_write (channel=0x7f96e0ae5800, buffer=0x7f96e09f9b40) at ../src/nvim/msgpack_rpc/channel.c:551
    0x000000000058567d in on_request_event (argv=0x7ffed792efa0) at ../src/nvim/msgpack_rpc/channel.c:523
    0x00000000005854c8 in handle_request (channel=0x7f96e0ae5800, request=0x7ffed792f1b8) at ../src/nvim/msgpack_rpc/channel.c:503
    0x00000000005850cb in parse_msgpack (channel=0x7f96e0ae5800) at ../src/nvim/msgpack_rpc/channel.c:423
    0x0000000000584f90 in receive_msgpack (stream=0x7f96e0a35218, rbuf=0x7f96e0d1d4c0, c=22, data=0x7f96e0ae5800, eof=false)
    at ../src/nvim/msgpack_rpc/channel.c:389
    0x00000000004d0b20 in read_event (argv=0x7ffed792f4a8) at ../src/nvim/event/rstream.c:190
    0x00000000004ce462 in multiqueue_process_events (this=0x7f96e18172d0) at ../src/nvim/event/multiqueue.c:150
    0x000000000059b630 in nv_event (cap=0x7ffed792f620) at ../src/nvim/normal.c:7908
    0x000000000058be69 in normal_execute (state=0x7ffed792f580, key=-25341) at ../src/nvim/normal.c:1137
    0x0000000000652463 in state_enter (s=0x7ffed792f580) at ../src/nvim/state.c:61
    0x000000000058a1fe in normal_enter (cmdwin=false, noexmode=false) at ../src/nvim/normal.c:467
    0x00000000005500c2 in main (argc=2, argv=0x7ffed792f8d8) at ../src/nvim/main.c:554

Alternative approach suggested by bfredl is to use close_cb of the
process. My unsuccessful attempt is below. (It seems close_cb is queued
too late, which is the similar problem addressed by this commit):

    commit 75fc12c6ab15711bdb7b18c6d42ec9d157f5145e
    Author: Justin M. Keyes &lt;justinkz@gmail.com&gt;
    Date:   Fri Aug 18 01:30:41 2017 +0200

        rpc: use Stream's close_cb instead of explicit check in receive_msgpack()

    diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c
    index 8371d3cd482e..e52da23cdc40 100644
    --- a/src/nvim/event/process.c
    +++ b/src/nvim/event/process.c
    @@ -416,6 +416,10 @@ static void on_process_exit(Process *proc)
     static void on_process_stream_close(Stream *stream, void *data)
     {
       Process *proc = data;
    +  ILOG("on_process_stream_close");
    +  if (proc-&gt;stream_close_cb != NULL) {
    +    proc-&gt;stream_close_cb(stream, proc-&gt;stream_close_data);
    +  }
       decref(proc);
     }

    diff --git a/src/nvim/event/process.h b/src/nvim/event/process.h
    index 5c00e8e7ecd5..34a8d54f6f8c 100644
    --- a/src/nvim/event/process.h
    +++ b/src/nvim/event/process.h
    @@ -26,6 +26,11 @@ struct process {
       Stream *in, *out, *err;
       process_exit_cb cb;
       internal_process_cb internal_exit_cb, internal_close_cb;
    +
    +  // Called when any of the process streams (in/out/err) closes.
    +  stream_close_cb stream_close_cb;
    +  void *stream_close_data;
    +
       bool closed, detach;
       MultiQueue *events;
     };
    @@ -50,6 +55,8 @@ static inline Process process_init(Loop *loop, ProcessType type, void *data)
         .closed = false,
         .internal_close_cb = NULL,
         .internal_exit_cb = NULL,
    +    .stream_close_cb = NULL,
    +    .stream_close_data = NULL,
         .detach = false
       };
     }
    diff --git a/src/nvim/event/stream.c b/src/nvim/event/stream.c
    index 7c865bfe1e8c..c8720d1e45d9 100644
    --- a/src/nvim/event/stream.c
    +++ b/src/nvim/event/stream.c
    @@ -95,7 +95,11 @@ void stream_close(Stream *stream, stream_close_cb on_stream_close, void *data)
     void stream_close_handle(Stream *stream)
       FUNC_ATTR_NONNULL_ALL
     {
    +  ILOG("stream=%d", stream);
    +  // LOG_CALLSTACK();
       if (stream-&gt;uvstream) {
    +    // problem:  this schedules on the queue, but channel.c:receive_msgpack may
    +    // be processed before close_cb is called by libuv.
         uv_close((uv_handle_t *)stream-&gt;uvstream, close_cb);
       } else {
         uv_close((uv_handle_t *)&amp;stream-&gt;uv.idle, close_cb);
    @@ -105,6 +109,7 @@ void stream_close_handle(Stream *stream)
     static void close_cb(uv_handle_t *handle)
     {
       Stream *stream = handle-&gt;data;
    +  ILOG("&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; stream=%p stream-&gt;internal_close_cb=%p", stream, stream-&gt;internal_close_cb);
       if (stream-&gt;buffer) {
         rbuffer_free(stream-&gt;buffer);
       }
    diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c
    index 782eabe04e4a..dc2b794e366a 100644
    --- a/src/nvim/msgpack_rpc/channel.c
    +++ b/src/nvim/msgpack_rpc/channel.c
    @@ -128,6 +128,8 @@ uint64_t channel_from_process(Process *proc, uint64_t id, char *source)
                                           source);
       incref(channel);  // process channels are only closed by the exit_cb
       channel-&gt;data.proc = proc;
    +  channel-&gt;data.proc-&gt;stream_close_cb = close_cb2;
    +  channel-&gt;data.proc-&gt;stream_close_data = channel;

       wstream_init(proc-&gt;in, 0);
       rstream_init(proc-&gt;out, 0);
    @@ -387,17 +389,6 @@ static void receive_msgpack(Stream *stream, RBuffer *rbuf, size_t c,
         goto end;
       }

    -  if ((chan_wstream(channel) != NULL &amp;&amp; chan_wstream(channel)-&gt;closed)
    -      || (chan_rstream(channel) != NULL &amp;&amp; chan_rstream(channel)-&gt;closed)) {
    -    char buf[256];
    -    snprintf(buf, sizeof(buf),
    -             "ch %" PRIu64 ": stream closed unexpectedly. "
    -             "closing channel",
    -             channel-&gt;id);
    -    call_set_error(channel, buf, WARN_LOG_LEVEL);
    -    goto end;
    -  }
    -
       size_t count = rbuffer_size(rbuf);
       DLOG("ch %" PRIu64 ": parsing %u bytes from msgpack Stream: %p",
            channel-&gt;id, count, stream);
    @@ -571,23 +562,6 @@ static Stream *chan_wstream(Channel *chan)
       abort();
     }

    -/// Returns the Stream that a Channel reads from.
    -static Stream *chan_rstream(Channel *chan)
    -{
    -  switch (chan-&gt;type) {
    -    case kChannelTypeSocket:
    -      return &amp;chan-&gt;data.stream;
    -    case kChannelTypeProc:
    -      return chan-&gt;data.proc-&gt;out;
    -    case kChannelTypeStdio:
    -      return &amp;chan-&gt;data.std.in;
    -    case kChannelTypeInternal:
    -      return NULL;
    -  }
    -  abort();
    -}
    -
    -
     static bool channel_write(Channel *channel, WBuffer *buffer)
     {
       bool success = false;
    @@ -799,6 +773,12 @@ static void close_cb(Stream *stream, void *data)
       decref(data);
     }

    +static void close_cb2(Stream *stream, void *data)
    +{
    +  ILOG("close_cb2");
    +  close_channel(data);
    +}
    +
     /// @param source description of source function, rplugin name, TCP addr, etc
     static Channel *register_channel(ChannelType type, uint64_t id,
                                      MultiQueue *events, char *source)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
f_jobstop()/f_rpcstop() .. process_stop() .. process_close_in(proc)
closes the write-stream of a RPC channel. But there might be
a pending RPC notification on the queue, which may get processed just
before the channel is closed.

To handle that case, check the Stream.closed in
channel.c:receive_msgpack().

Before this change, the above scenario could trigger
this assert(!stream-&gt;closed) in wstream_write():

    0x00007f96e1cd3428 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:54
    0x00007f96e1cd502a in __GI_abort () at abort.c:89
    0x00007f96e1ccbbd7 in __assert_fail_base (fmt=&lt;optimized out&gt;, assertion=assertion@entry=0x768f9b "!stream-&gt;closed",
    file=file@entry=0x768f70 "../src/nvim/event/wstream.c", line=line@entry=77,
    function=function@entry=0x768fb0 &lt;__PRETTY_FUNCTION__.13735&gt; "wstream_write") at assert.c:92
    0x00007f96e1ccbc82 in __GI___assert_fail (assertion=0x768f9b "!stream-&gt;closed", file=0x768f70 "../src/nvim/event/wstream.c", line=77,
    function=0x768fb0 &lt;__PRETTY_FUNCTION__.13735&gt; "wstream_write") at assert.c:101
    0x00000000004d2c1f in wstream_write (stream=0x7f96e0a35078, buffer=0x7f96e09f9b40) at ../src/nvim/event/wstream.c:77
    0x00000000005857b2 in channel_write (channel=0x7f96e0ae5800, buffer=0x7f96e09f9b40) at ../src/nvim/msgpack_rpc/channel.c:551
    0x000000000058567d in on_request_event (argv=0x7ffed792efa0) at ../src/nvim/msgpack_rpc/channel.c:523
    0x00000000005854c8 in handle_request (channel=0x7f96e0ae5800, request=0x7ffed792f1b8) at ../src/nvim/msgpack_rpc/channel.c:503
    0x00000000005850cb in parse_msgpack (channel=0x7f96e0ae5800) at ../src/nvim/msgpack_rpc/channel.c:423
    0x0000000000584f90 in receive_msgpack (stream=0x7f96e0a35218, rbuf=0x7f96e0d1d4c0, c=22, data=0x7f96e0ae5800, eof=false)
    at ../src/nvim/msgpack_rpc/channel.c:389
    0x00000000004d0b20 in read_event (argv=0x7ffed792f4a8) at ../src/nvim/event/rstream.c:190
    0x00000000004ce462 in multiqueue_process_events (this=0x7f96e18172d0) at ../src/nvim/event/multiqueue.c:150
    0x000000000059b630 in nv_event (cap=0x7ffed792f620) at ../src/nvim/normal.c:7908
    0x000000000058be69 in normal_execute (state=0x7ffed792f580, key=-25341) at ../src/nvim/normal.c:1137
    0x0000000000652463 in state_enter (s=0x7ffed792f580) at ../src/nvim/state.c:61
    0x000000000058a1fe in normal_enter (cmdwin=false, noexmode=false) at ../src/nvim/normal.c:467
    0x00000000005500c2 in main (argc=2, argv=0x7ffed792f8d8) at ../src/nvim/main.c:554

Alternative approach suggested by bfredl is to use close_cb of the
process. My unsuccessful attempt is below. (It seems close_cb is queued
too late, which is the similar problem addressed by this commit):

    commit 75fc12c6ab15711bdb7b18c6d42ec9d157f5145e
    Author: Justin M. Keyes &lt;justinkz@gmail.com&gt;
    Date:   Fri Aug 18 01:30:41 2017 +0200

        rpc: use Stream's close_cb instead of explicit check in receive_msgpack()

    diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c
    index 8371d3cd482e..e52da23cdc40 100644
    --- a/src/nvim/event/process.c
    +++ b/src/nvim/event/process.c
    @@ -416,6 +416,10 @@ static void on_process_exit(Process *proc)
     static void on_process_stream_close(Stream *stream, void *data)
     {
       Process *proc = data;
    +  ILOG("on_process_stream_close");
    +  if (proc-&gt;stream_close_cb != NULL) {
    +    proc-&gt;stream_close_cb(stream, proc-&gt;stream_close_data);
    +  }
       decref(proc);
     }

    diff --git a/src/nvim/event/process.h b/src/nvim/event/process.h
    index 5c00e8e7ecd5..34a8d54f6f8c 100644
    --- a/src/nvim/event/process.h
    +++ b/src/nvim/event/process.h
    @@ -26,6 +26,11 @@ struct process {
       Stream *in, *out, *err;
       process_exit_cb cb;
       internal_process_cb internal_exit_cb, internal_close_cb;
    +
    +  // Called when any of the process streams (in/out/err) closes.
    +  stream_close_cb stream_close_cb;
    +  void *stream_close_data;
    +
       bool closed, detach;
       MultiQueue *events;
     };
    @@ -50,6 +55,8 @@ static inline Process process_init(Loop *loop, ProcessType type, void *data)
         .closed = false,
         .internal_close_cb = NULL,
         .internal_exit_cb = NULL,
    +    .stream_close_cb = NULL,
    +    .stream_close_data = NULL,
         .detach = false
       };
     }
    diff --git a/src/nvim/event/stream.c b/src/nvim/event/stream.c
    index 7c865bfe1e8c..c8720d1e45d9 100644
    --- a/src/nvim/event/stream.c
    +++ b/src/nvim/event/stream.c
    @@ -95,7 +95,11 @@ void stream_close(Stream *stream, stream_close_cb on_stream_close, void *data)
     void stream_close_handle(Stream *stream)
       FUNC_ATTR_NONNULL_ALL
     {
    +  ILOG("stream=%d", stream);
    +  // LOG_CALLSTACK();
       if (stream-&gt;uvstream) {
    +    // problem:  this schedules on the queue, but channel.c:receive_msgpack may
    +    // be processed before close_cb is called by libuv.
         uv_close((uv_handle_t *)stream-&gt;uvstream, close_cb);
       } else {
         uv_close((uv_handle_t *)&amp;stream-&gt;uv.idle, close_cb);
    @@ -105,6 +109,7 @@ void stream_close_handle(Stream *stream)
     static void close_cb(uv_handle_t *handle)
     {
       Stream *stream = handle-&gt;data;
    +  ILOG("&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; stream=%p stream-&gt;internal_close_cb=%p", stream, stream-&gt;internal_close_cb);
       if (stream-&gt;buffer) {
         rbuffer_free(stream-&gt;buffer);
       }
    diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c
    index 782eabe04e4a..dc2b794e366a 100644
    --- a/src/nvim/msgpack_rpc/channel.c
    +++ b/src/nvim/msgpack_rpc/channel.c
    @@ -128,6 +128,8 @@ uint64_t channel_from_process(Process *proc, uint64_t id, char *source)
                                           source);
       incref(channel);  // process channels are only closed by the exit_cb
       channel-&gt;data.proc = proc;
    +  channel-&gt;data.proc-&gt;stream_close_cb = close_cb2;
    +  channel-&gt;data.proc-&gt;stream_close_data = channel;

       wstream_init(proc-&gt;in, 0);
       rstream_init(proc-&gt;out, 0);
    @@ -387,17 +389,6 @@ static void receive_msgpack(Stream *stream, RBuffer *rbuf, size_t c,
         goto end;
       }

    -  if ((chan_wstream(channel) != NULL &amp;&amp; chan_wstream(channel)-&gt;closed)
    -      || (chan_rstream(channel) != NULL &amp;&amp; chan_rstream(channel)-&gt;closed)) {
    -    char buf[256];
    -    snprintf(buf, sizeof(buf),
    -             "ch %" PRIu64 ": stream closed unexpectedly. "
    -             "closing channel",
    -             channel-&gt;id);
    -    call_set_error(channel, buf, WARN_LOG_LEVEL);
    -    goto end;
    -  }
    -
       size_t count = rbuffer_size(rbuf);
       DLOG("ch %" PRIu64 ": parsing %u bytes from msgpack Stream: %p",
            channel-&gt;id, count, stream);
    @@ -571,23 +562,6 @@ static Stream *chan_wstream(Channel *chan)
       abort();
     }

    -/// Returns the Stream that a Channel reads from.
    -static Stream *chan_rstream(Channel *chan)
    -{
    -  switch (chan-&gt;type) {
    -    case kChannelTypeSocket:
    -      return &amp;chan-&gt;data.stream;
    -    case kChannelTypeProc:
    -      return chan-&gt;data.proc-&gt;out;
    -    case kChannelTypeStdio:
    -      return &amp;chan-&gt;data.std.in;
    -    case kChannelTypeInternal:
    -      return NULL;
    -  }
    -  abort();
    -}
    -
    -
     static bool channel_write(Channel *channel, WBuffer *buffer)
     {
       bool success = false;
    @@ -799,6 +773,12 @@ static void close_cb(Stream *stream, void *data)
       decref(data);
     }

    +static void close_cb2(Stream *stream, void *data)
    +{
    +  ILOG("close_cb2");
    +  close_channel(data);
    +}
    +
     /// @param source description of source function, rplugin name, TCP addr, etc
     static Channel *register_channel(ChannelType type, uint64_t id,
                                      MultiQueue *events, char *source)
</pre>
</div>
</content>
</entry>
<entry>
<title>log: some DEBUG-level stream logging</title>
<updated>2017-08-20T23:04:28+00:00</updated>
<author>
<name>Justin M. Keyes</name>
<email>justinkz@gmail.com</email>
</author>
<published>2017-07-26T22:30:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.josher.dev/cgit/rneovim.git/commit/?id=e006b1d98d92aead6aff565ed5d8b034772aa16c'/>
<id>e006b1d98d92aead6aff565ed5d8b034772aa16c</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>log: caller provides the source details</title>
<updated>2017-07-23T13:01:31+00:00</updated>
<author>
<name>Justin M. Keyes</name>
<email>justinkz@gmail.com</email>
</author>
<published>2017-07-19T08:27:34+00:00</published>
<link rel='alternate' type='text/html' href='https://git.josher.dev/cgit/rneovim.git/commit/?id=bc6a3fe78445f41851f30c6f55e11b6b1ed5feaf'/>
<id>bc6a3fe78445f41851f30c6f55e11b6b1ed5feaf</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>log: channel registration</title>
<updated>2017-07-22T19:26:03+00:00</updated>
<author>
<name>Justin M. Keyes</name>
<email>justinkz@gmail.com</email>
</author>
<published>2017-07-19T00:24:12+00:00</published>
<link rel='alternate' type='text/html' href='https://git.josher.dev/cgit/rneovim.git/commit/?id=502af39f6261e1d1b71df7fa3169e943707ee7f2'/>
<id>502af39f6261e1d1b71df7fa3169e943707ee7f2</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>log: Always enable; remove DISABLE_LOG</title>
<updated>2017-06-06T22:26:21+00:00</updated>
<author>
<name>Justin M. Keyes</name>
<email>justinkz@gmail.com</email>
</author>
<published>2017-05-30T00:03:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.josher.dev/cgit/rneovim.git/commit/?id=fe1af9c2bc020cdb9e1e86e1f16d6060246f957a'/>
<id>fe1af9c2bc020cdb9e1e86e1f16d6060246f957a</id>
<content type='text'>
- Establish ERROR log level as "critical". Such errors are rare and will
  be valuable when users encounter unusual circumstances.
- Set -DMIN_LOG_LEVEL=3 for release-type builds
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
- Establish ERROR log level as "critical". Such errors are rare and will
  be valuable when users encounter unusual circumstances.
- Set -DMIN_LOG_LEVEL=3 for release-type builds
</pre>
</div>
</content>
</entry>
<entry>
<title>channel_write: fix compiler warning</title>
<updated>2017-05-31T12:10:04+00:00</updated>
<author>
<name>Justin M. Keyes</name>
<email>justinkz@gmail.com</email>
</author>
<published>2017-05-31T01:37:29+00:00</published>
<link rel='alternate' type='text/html' href='https://git.josher.dev/cgit/rneovim.git/commit/?id=fcc9d999670c6fb29ac01e9c8d0a7e787ccfabea'/>
<id>fcc9d999670c6fb29ac01e9c8d0a7e787ccfabea</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>sockets: don't deadlock when connecting to own pipe address</title>
<updated>2017-05-29T17:02:49+00:00</updated>
<author>
<name>Björn Linse</name>
<email>bjorn.linse@gmail.com</email>
</author>
<published>2017-05-06T07:31:36+00:00</published>
<link rel='alternate' type='text/html' href='https://git.josher.dev/cgit/rneovim.git/commit/?id=5a151555c8dce70bbf235e7f6d5bd1ced5e7c46c'/>
<id>5a151555c8dce70bbf235e7f6d5bd1ced5e7c46c</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
</feed>
