[uim-commit] r802 - trunk/uim

ekato at freedesktop.org ekato at freedesktop.org
Sun Mar 20 09:19:40 PST 2005


Author: ekato
Date: 2005-03-20 09:19:36 -0800 (Sun, 20 Mar 2005)
New Revision: 802

Modified:
   trunk/uim/uim-helper-client.c
   trunk/uim/uim-helper-server.c
   trunk/uim/uim-helper.c
Log:
* uim/uim-helper-client.c : Use blocking IO again.
* uim/uim-helper.c (uim_helper_send_message) : Write all data with
  blocking IO.
* uim/uim-helper-server.c (s_fdset_read) : New variable.
(s_fdset_write) : New variable.
(s_max_fd) : New variable used for select(2).
(struct client) : Add new member write_queue.
(init_serv_fd) : Set fd for select(2) here.
(get_unused_client) : Setup write queue.
(free_client) : Reset write queue.
(parse_content) : Don't write(2) data here.  Just setup a write
  queue and prepare it for select(2).
(shift_buffer) : New function.
(uim_helper_server_get_message) : New function.  Separate received
  buffer into meaningful messages.
(proc_func) : Don't return -1 even if read(2) fails when errno is
  EAGAIN or EINTR.  Change to call parse_conentt() with each
  message instead of message blocks.
(uim_helper_server_process_connection) : Call select(2) with write
  fd in addition to read fd.


Modified: trunk/uim/uim-helper-client.c
===================================================================
--- trunk/uim/uim-helper-client.c	2005-03-19 13:51:27 UTC (rev 801)
+++ trunk/uim/uim-helper-client.c	2005-03-20 17:19:36 UTC (rev 802)
@@ -42,7 +42,6 @@
 #include <string.h>
 #include <sys/stat.h>
 #include <unistd.h>
-#include <fcntl.h>
 #include "uim.h"
 #include "uim-helper.h"
 #include "context.h"
@@ -71,7 +70,6 @@
   int fd;
   struct sockaddr_un server;
   char *path = uim_helper_get_pathname();
-  int flag;
   
   uim_fd = -1;
   
@@ -125,17 +123,6 @@
     return -1;
   }
 
-  if ((flag = fcntl(fd, F_GETFL)) == -1) {
-    close(fd);
-    return -1;
-  }
-
-  flag |= O_NONBLOCK;
-  if (fcntl(fd, F_SETFL, flag) == -1) {
-    close(fd);
-    return -1;
-  }
-
   uim_read_buf = strdup("");
   uim_disconnect_cb = disconnect_cb;
   uim_fd = fd;
@@ -211,7 +198,7 @@
       uim_fd = -1;
       return;
     }
-    uim_read_buf = (char *)realloc(uim_read_buf, strlen(uim_read_buf) + strlen(buf)+1);
+    uim_read_buf = (char *)realloc(uim_read_buf, strlen(uim_read_buf) + strlen(buf) + 1);
     strcat(uim_read_buf, buf);
   }
   uim_read_buf_size = strlen(uim_read_buf);
@@ -235,11 +222,11 @@
 
   for (i = 0; i < uim_read_buf_size - 1; i++) {
     if (uim_read_buf[i] == '\n' &&
-	uim_read_buf[i+1] == '\n') {
-      buf = (char *)malloc(i+2);
-      memcpy(buf, uim_read_buf, i+1);
-      buf[i+1] = '\0';
-      shift_read_buffer(i+2);
+	uim_read_buf[i + 1] == '\n') {
+      buf = (char *)malloc(i + 2);
+      memcpy(buf, uim_read_buf, i + 1);
+      buf[i + 1] = '\0';
+      shift_read_buffer(i + 2);
       return buf;
     }
   }

Modified: trunk/uim/uim-helper-server.c
===================================================================
--- trunk/uim/uim-helper-server.c	2005-03-19 13:51:27 UTC (rev 801)
+++ trunk/uim/uim-helper-server.c	2005-03-20 17:19:36 UTC (rev 802)
@@ -57,10 +57,15 @@
   (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
 #endif
 
+static fd_set s_fdset_read;
+static fd_set s_fdset_write;
+static int s_max_fd;
+
 static int nr_client_slots;
 static struct client {
   int fd;
   char *rbuf;
+  char *write_queue;
 } *clients;
 
 /*
@@ -118,6 +123,8 @@
     return -1;
   }
   /*  fprintf(stderr,"listen at %s\n",path);*/
+  FD_SET(fd, &s_fdset_read);
+  s_max_fd = fd;
   return fd;
 }
 
@@ -130,9 +137,10 @@
       return &clients[i];
     }
   }
-  nr_client_slots ++;
+  nr_client_slots++;
   clients = realloc(clients, sizeof(struct client) * nr_client_slots);
   clients[nr_client_slots - 1].rbuf = strdup("");
+  clients[nr_client_slots - 1].write_queue = strdup("");
   return &clients[nr_client_slots - 1];
 }
 
@@ -143,6 +151,10 @@
     free(cl->rbuf);
     cl->rbuf = strdup("");
   }
+  if (cl->write_queue) {
+    free(cl->write_queue);
+    cl->write_queue = strdup("");
+  }
   cl->fd = -1;
 }
 
@@ -150,9 +162,7 @@
 static void
 parse_content(char *content, struct client *cl)
 {
-  int i;
-  int ret, content_len, out_len;
-  char *out;
+  int i, content_len;
 
   content_len = strlen(content);
 
@@ -160,38 +170,39 @@
     if (clients[i].fd == -1 || clients[i].fd == cl->fd) {
       continue;
     } else {
-      out = content;
-      out_len = content_len;
-      while (out_len > 0) {
-	if ((ret = write(clients[i].fd, out, out_len)) < 0) {
-	  if (errno == EAGAIN || errno == EINTR) {
-	    fd_set fds;
-	    struct timeval tv;
-	    int rc;
+      clients[i].write_queue = (char *)realloc(clients[i].write_queue,
+		      strlen(clients[i].write_queue) + content_len + 1);
+      strcat(clients[i].write_queue, content);
+      FD_SET(clients[i].fd, &s_fdset_write);
+    }
+  }
+}
 
-	    FD_ZERO(&fds);
-	    FD_SET(clients[i].fd, &fds);
-	    tv.tv_sec = 10;
-	    tv.tv_usec = 0;
-	    rc = select(clients[i].fd + 1, NULL, &fds, NULL, &tv);
-	    if (rc > 0 && FD_ISSET(clients[i].fd, &fds)) {
-	      continue;
-	    }
-	    fprintf(stderr, "uim-helper-server failed to write\n");
-	  }
+static void
+shift_buffer(char *buf, int count)
+{
+  int len = strlen(buf);
+  memmove(buf, &buf[count], len - count);
+  buf[len - count] = '\0';
+}
 
-      	  if (errno == EPIPE) {
-	    close(clients[i].fd);
-	    free_client(&clients[i]);
-	  }
-	  break;
-	}
+static char *
+uim_helper_server_get_message(char *buf)
+{
+  int i;
+  int len = strlen(buf);
+  char *ret;
 
-	out += ret;
-	out_len -= ret;
-      }
+  for (i = 0; i < len - 1; i++) {
+    if (buf[i] == '\n' && buf[i + 1] == '\n') {
+      ret = (char *)malloc(i + 3);
+      memcpy(ret, buf, i + 2);
+      ret[i + 2] = '\0';
+      shift_buffer(buf, i + 2);
+      return ret;
     }
   }
+  return NULL;
 }
 
 static int
@@ -199,10 +210,13 @@
 {
   int rc;
   char buf[BUFFER_SIZE];
+  char *message;
 
   /* do read */
   rc = read(cl->fd, buf, BUFFER_SIZE - 1);
   if (rc <= 0) {
+    if (rc < 0 && (errno == EAGAIN || errno == EINTR))
+      return 0;
     return -1;
   }
 
@@ -211,13 +225,11 @@
   cl->rbuf = (char *)realloc(cl->rbuf, strlen(cl->rbuf) + strlen(buf) + 1);
   strcat(cl->rbuf, buf);
 
-  if (uim_helper_str_terminated(cl->rbuf)) {
+  while ((message = uim_helper_server_get_message(cl->rbuf))) {
     /* process */
-    parse_content(cl->rbuf, cl);
-    free(cl->rbuf);
-    cl->rbuf = strdup("");
+    parse_content(message, cl);
+    free(message);
   }
-
   return 1;
 }
 
@@ -225,29 +237,19 @@
 uim_helper_server_process_connection(int serv_fd)
 {
   int i;
-  int fd_biggest = 0;
   fd_set readfds;
+  fd_set writefds;
+  struct timeval tv;
 
-  fd_biggest = serv_fd;
-
   while (1) {
-    /* setup readfds */
-    FD_ZERO(&readfds);
-    FD_SET(serv_fd, &readfds);  
-    for (i = 0; i < nr_client_slots; i++) {
-      int fd = clients[i].fd;
-      if (fd == -1) {
-	continue;
-      }
-      FD_SET(fd, &readfds);
-      if (fd > fd_biggest) {
-	fd_biggest = fd;
-      }
-    }
+    memcpy(&readfds, &s_fdset_read, sizeof(fd_set));
+    memcpy(&writefds, &s_fdset_write, sizeof(fd_set));
+    tv.tv_sec = 1;
+    tv.tv_usec = 0;
 
     /* call select(), waiting until a file descriptor readable */
-    if (select(fd_biggest + 1, &readfds, NULL, NULL, NULL) < 0) {
-      perror("select faild");
+    if (select(s_max_fd + 1, &readfds, &writefds, NULL, &tv) <= 0) {
+      continue;
     }
 
     /* for accept new connection */
@@ -287,19 +289,53 @@
 	write(cl->fd, buf, 1);
       }
 #endif
+      FD_SET(cl->fd, &s_fdset_read);
+      if (cl->fd > s_max_fd)
+	s_max_fd = cl->fd;
     } else {
-      /* check data from clients reached */
+      /* check data to write and from clients reached */
       for (i = 0; i < nr_client_slots; i++) {
-	if (clients[i].fd != -1 &&
-	  FD_ISSET(clients[i].fd, &readfds)) {
+	if (clients[i].fd != -1 && FD_ISSET(clients[i].fd, &writefds)) {
+	  int ret, message_len, out_len;
+	  char *out;
+
+	  out = clients[i].write_queue;
+	  message_len = out_len = strlen(clients[i].write_queue);
+	  while (out_len > 0) {
+	    if ((ret = write(clients[i].fd, out, out_len)) < 0) {
+	      perror("uim-helper_server write(2) failed");
+	      if (errno == EPIPE) {
+	        FD_CLR(clients[i].fd, &s_fdset_read);
+	        FD_CLR(clients[i].fd, &s_fdset_write);
+	        if (clients[i].fd == s_max_fd)
+	          s_max_fd--;
+	        close(clients[i].fd);
+	        free_client(&clients[i]);
+	      }
+	      break;
+	    } else {
+	      out += ret;
+	      out_len -= ret;
+	    }
+	  }
+	  if (out_len == 0) {
+	    free(clients[i].write_queue);
+	    clients[i].write_queue = strdup("");
+	    FD_CLR(clients[i].fd, &s_fdset_write);
+	  } else {
+	    shift_buffer(clients[i].write_queue, message_len - out_len);
+	  }
+	}
+	if (clients[i].fd != -1 && FD_ISSET(clients[i].fd, &readfds)) {
 	  int result;
 	  /* actual process */
 	  result = proc_func(&clients[i]);
 
 	  if (result < 0) {
-	    FD_CLR(clients[i].fd, &readfds);
-	    if (clients[i].fd == fd_biggest)
-	      fd_biggest--;
+	    FD_CLR(clients[i].fd, &s_fdset_read);
+	    FD_CLR(clients[i].fd, &s_fdset_write);
+	    if (clients[i].fd == s_max_fd)
+	      s_max_fd--;
 	    close(clients[i].fd);
 	    free_client(&clients[i]);
 	  }
@@ -319,6 +355,9 @@
   clients = NULL;
   nr_client_slots = 0;
 
+  FD_ZERO(&s_fdset_read);
+  FD_ZERO(&s_fdset_write);
+  s_max_fd = 0;
   serv_fd = init_serv_fd(path);
 
   printf("waiting\n\n");

Modified: trunk/uim/uim-helper.c
===================================================================
--- trunk/uim/uim-helper.c	2005-03-19 13:51:27 UTC (rev 801)
+++ trunk/uim/uim-helper.c	2005-03-20 17:19:36 UTC (rev 802)
@@ -134,21 +134,8 @@
   bufp = buf;
   while (out_len > 0) {
     if ((res = write(fd, bufp, out_len)) < 0) {
-      if (errno == EAGAIN || errno == EINTR) {
-	fd_set fds;
-	struct timeval tv;
-	int rc;
-
-	FD_ZERO(&fds);
-	FD_SET(fd, &fds);
-	tv.tv_sec = 2;
-	tv.tv_usec = 0;
-	rc = select(fd + 1, NULL, &fds, NULL, &tv);
-	if (rc > 0 && FD_ISSET(fd, &fds)) {
-	  continue;
-	}
-	fprintf(stderr, "uim_helper_send_message: write failed\n");
-      }
+      if (errno == EAGAIN || errno == EINTR)
+	continue;
       break;
     }
 
@@ -200,9 +187,9 @@
   if (!str)
     return 0;
 
-  if (strlen(str) > 2&&
-     str[strlen(str)-1] == '\n' &&
-     str[strlen(str)-2] == '\n' )
+  if (strlen(str) > 2 &&
+     str[strlen(str) - 1] == '\n' &&
+     str[strlen(str) - 2] == '\n')
     return 1;
 
   return 0;



More information about the Uim-commit mailing list