diff src/channel.c @ 7743:6069f43cea4e v7.4.1169

commit https://github.com/vim/vim/commit/e0874f8cbcddfcf9965a85ba35199964efb1d01a Author: Bram Moolenaar <Bram@vim.org> Date: Sun Jan 24 20:36:41 2016 +0100 patch 7.4.1169 Problem: The socket I/O is intertwined with the netbeans code. Solution: Start refactoring the netbeans communication to split off the socket I/O. Add the +channel feature.
author Christian Brabandt <cb@256bit.org>
date Sun, 24 Jan 2016 20:45:05 +0100
parents
children 42c1a4e63d12
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/src/channel.c
@@ -0,0 +1,187 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ */
+
+/*
+ * Implements communication through a socket or any file handle.
+ */
+
+#include "vim.h"
+
+#if defined(FEAT_CHANNEL) || defined(PROTO)
+
+typedef struct {
+    sock_T  ch_fd;
+    int	    ch_idx;
+} channel_T;
+
+static channel_T *channels = NULL;
+static int channel_count = 0;
+
+/*
+ * Add a new channel slot, return the index.
+ * Returns -1 if out of space.
+ */
+    static int
+add_channel(void)
+{
+    int		idx;
+    channel_T	*new_channels;
+
+    if (channels != NULL)
+	for (idx = 0; idx < channel_count; ++idx)
+	    if (channels[idx].ch_fd < 0)
+		/* re-use a closed channel slot */
+		return idx;
+    if (channel_count == MAX_OPEN_CHANNELS)
+	return -1;
+    new_channels = (channel_T *)alloc(sizeof(channel_T) * channel_count + 1);
+    if (new_channels == NULL)
+	return -1;
+    if (channels != NULL)
+	mch_memmove(new_channels, channels, sizeof(channel_T) * channel_count);
+    channels = new_channels;
+    channels[channel_count].ch_fd = (sock_T)-1;
+
+    return channel_count++;
+}
+
+#if defined(FEAT_NETBEANS_INTG) || defined(PROTO)
+static int netbeans_channel = -1;
+
+/*
+ * Add the netbeans socket to the channels.
+ * Return the channel index.
+ */
+    int
+channel_add_netbeans(sock_T fd)
+{
+    int idx = add_channel();
+
+    if (idx >= 0)
+    {
+	channels[idx].ch_fd = fd;
+	netbeans_channel = idx;
+    }
+    return idx;
+}
+
+    void
+channel_remove_netbeans()
+{
+    channels[netbeans_channel].ch_fd = (sock_T)-1;
+    netbeans_channel = -1;
+}
+#endif
+
+    static void
+channel_read(int idx)
+{
+# ifdef FEAT_NETBEANS_INTG
+    if (idx == netbeans_channel)
+	netbeans_read();
+    else
+# endif
+    {
+	; /* TODO: read */
+    }
+}
+
+#if (defined(UNIX) && !defined(HAVE_SELECT)) || defined(PROTO)
+/*
+ * Add open channels to the poll struct.
+ * Return the adjusted struct index.
+ * The type of "fds" is hidden to avoid problems with the function proto.
+ */
+    int
+channel_poll_setup(int nfd_in, void *fds_in)
+{
+    int nfd = nfd_in;
+    int i;
+    struct pollfd *fds = fds_in;
+
+    for (i = 0; i < channel_count; ++i)
+	if (channels[i].ch_fd >= 0)
+	{
+	    channels[i].ch_idx = nfd;
+	    fds[nfd].fd = channels[i].ch_fd;
+	    fds[nfd].events = POLLIN;
+	    nfd++;
+	}
+	else
+	    channels[i].ch_idx = -1;
+
+    return nfd;
+}
+
+/*
+ * The type of "fds" is hidden to avoid problems with the function proto.
+ */
+    int
+channel_poll_check(int ret_in, void *fds_in)
+{
+    int ret = ret_in;
+    int i;
+    struct pollfd *fds = fds_in;
+
+    for (i = 0; i < channel_count; ++i)
+	if (ret > 0 && channels[i].ch_idx != -1
+				 && fds[channels[i].ch_idx].revents & POLLIN)
+	{
+	    channel_read(i);
+	    --ret;
+	}
+
+    return ret;
+}
+#endif /* UNIX && !HAVE_SELECT */
+
+#if (defined(UNIX) && defined(HAVE_SELECT)) || defined(PROTO)
+/*
+ * The type of "rfds" is hidden to avoid problems with the function proto.
+ */
+    int
+channel_select_setup(int maxfd_in, void *rfds_in)
+{
+    int	    maxfd = maxfd_in;
+    int	    i;
+    fd_set  *rfds = rfds_in;
+
+    for (i = 0; i < channel_count; ++i)
+	if (channels[i].ch_fd >= 0)
+	{
+	    FD_SET(channels[i].ch_fd, rfds);
+	    if (maxfd < channels[i].ch_fd)
+		maxfd = channels[i].ch_fd;
+	}
+
+    return maxfd;
+}
+
+/*
+ * The type of "rfds" is hidden to avoid problems with the function proto.
+ */
+    int
+channel_select_check(int ret_in, void *rfds_in)
+{
+    int	    ret = ret_in;
+    int	    i;
+    fd_set  *rfds = rfds_in;
+
+    for (i = 0; i < channel_count; ++i)
+	if (ret > 0 && channels[i].ch_fd >= 0
+				       && FD_ISSET(channels[i].ch_fd, rfds))
+	{
+	    channel_read(i);
+	    --ret;
+	}
+
+    return ret;
+}
+#endif /* UNIX && HAVE_SELECT */
+
+#endif /* FEAT_CHANNEL */