[Freeswitch-branches] [commit] r4729 - in freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip: . libsofia-sip-ua/su libsofia-sip-ua/su/sofia-sip m4

Freeswitch SVN mikej at freeswitch.org
Thu Mar 22 10:41:43 EDT 2007


Author: mikej
Date: Thu Mar 22 10:41:43 2007
New Revision: 4729

Modified:
   freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/Makefile.am
   freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/htable.h
   freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/htable2.h
   freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/su/su_kqueue_port.c
   freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/su/test_htable.c
   freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/su/test_memmem.c
   freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/m4/sac-tport.m4

Log:
updates from sofia-sip darcs tree:


Wed Mar 21 06:15:56 EDT 2007  Pekka Pessi <Pekka.Pessi at nokia.com>
  * Makefile.am, m4/sac-tport.m4: fixes for Solaris

Wed Mar 21 06:40:04 EDT 2007  Pekka Pessi <first.lastname at nokia.com>
  * sofia-sip/htable.h: do not fail assert in htable_remove() if entry is not found

  Changed htable_remove() prototype, it now returns -1.

Wed Mar 21 11:36:40 EDT 2007  Pekka Pessi <first.lastname at nokia.com>
  * test_memmem.c: warn about bad system memmem(), do not fail.

Wed Mar 21 11:37:18 EDT 2007  Pekka Pessi <first.lastname at nokia.com>
  * su_kqueue_port.c: using correct kqueue semantics



Modified: freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/Makefile.am
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/Makefile.am	(original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/Makefile.am	Thu Mar 22 10:41:43 2007
@@ -49,6 +49,11 @@
 CLEANFILES = $(dist_man_MANS)
 
 coverage built-sources clean-built-sources valcheck doxygen:
-	for i in libsofia-sip-ua $(GLIB_SUBDIRS) ; do $(MAKE) $(AM_MAKEFLAGS) -C $$i $@ ; done
+	@failcom='exit 1'; for f in x $$MAKEFLAGS; do \
+	case $$f in *=* | --[!k]*);; *k*) failcom='fail=yes';; esac; done; \
+	for i in libsofia-sip-ua $(GLIB_SUBDIRS) ; do \
+	  (cd $$i && $(MAKE) $(AM_MAKEFLAGS) $@) || eval $$failcom; \
+	done ; \
+	test -z "$$fail"
 
-.PHONY: coverage built-sources clean-built-sources doxygen manpages
+.PHONY: coverage built-sources clean-built-sources valcheck doxygen manpages

Modified: freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/htable.h
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/htable.h	(original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/htable.h	Thu Mar 22 10:41:43 2007
@@ -106,7 +106,7 @@
 HTABLE_SCOPE entry_t **prefix##_next(prefix##_t const *, entry_t * const *ee); \
 HTABLE_SCOPE void prefix##_append(prefix##_t *pr, entry_t const *e); \
 HTABLE_SCOPE void prefix##_insert(prefix##_t *pr, entry_t const *e); \
-HTABLE_SCOPE void prefix##_remove(prefix##_t *, entry_t const *e)
+HTABLE_SCOPE int prefix##_remove(prefix##_t *, entry_t const *e)
 
 /** Hash table implementation.
  *
@@ -220,13 +220,13 @@
 } \
 \
 HTABLE_SCOPE \
-void prefix##_remove(prefix##_t *pr, entry_t const *e) \
+int prefix##_remove(prefix##_t *pr, entry_t const *e) \
 { \
   size_t i, j, k; \
   size_t size = pr->pr##_size; \
   entry_t **htable = pr->pr##_table; \
 \
-  if (!e) return; \
+  if (!e) return -1; \
 \
   /* Search for entry */ \
   for (i = hfun(e) % size; htable[i]; i = (i + 1) % size) \
@@ -234,7 +234,7 @@
       break; \
 \
   /* Entry is not in table? */ \
-  assert(htable[i]); if (!e) return; \
+  if (!htable[i]) return -1; \
 \
   /* Move table entries towards their primary place  */ \
   for (j = (i + 1) % size; htable[j]; j = (j + 1) % size) { \
@@ -252,6 +252,8 @@
   pr->pr##_used--; \
 \
   htable[i] = NULL; \
+\
+  return 0; \
 } \
 extern int prefix##_dummy
 

Modified: freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/htable2.h
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/htable2.h	(original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/htable2.h	Thu Mar 22 10:41:43 2007
@@ -240,7 +240,7 @@
     if (is_equal(e, htable[i])) \
       break; \
 \
-  assert(is_used(htable[i])); if (!is_used(htable[i])) return -1; \
+  if (!is_used(htable[i])) return -1; \
 \
   /* Move table entries towards their primary place  */ \
   for (j = (i + 1) % size; is_used(htable[j]); j = (j + 1) % size) { \

Modified: freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/su/su_kqueue_port.c
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/su/su_kqueue_port.c	(original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/su/su_kqueue_port.c	Thu Mar 22 10:41:43 2007
@@ -28,6 +28,7 @@
  * Port implementation using kqueue()
  *
  * @author Martti Mela <Martti.Mela at nokia.com>
+ * @author Pekka Pessi <Pekka.Pessi at nokia.com>
  *
  * @date Created: Sun Feb 18 19:55:37 EET 2007 mela
  */
@@ -43,6 +44,8 @@
 
 #include "sofia-sip/su_alloc.h"
 
+#include <sys/event.h>
+
 #define SU_ENABLE_MULTISHOT_KQUEUE 1
 
 #include <stdlib.h>
@@ -68,28 +71,21 @@
 				      su_port_register() or 
 				      su_port_unregister()
 				   */
-
-  int              sup_n_waits; /**< Active su_wait_t in su_waits */
-  int              sup_size_waits; /**< Size of allocated su_waits */
-  int              sup_pri_offset; /**< Offset to prioritized waits */
+  int              sup_n_registrations;
+  int              sup_max_index; /**< Indexes are equal or smaller than this */
+  int              sup_size_indices; /**< Size of allocated index table */
 
 #define INDEX_MAX (0x7fffffff)
 
-  /** Indices from index returned by su_root_register() to tables below. 
-   *
-   * Free elements are negative. Free elements form a list, value of free
-   * element is (0 - index of next free element).
-   *
-   * First element sup_indices[0] points to first free element. 
-   */
-  int             *sup_indices;
-
-  int             *sup_reverses; /** Reverse index */
-  su_wakeup_f     *sup_wait_cbs; 
-  su_wakeup_arg_t**sup_wait_args; 
-  su_root_t      **sup_wait_roots; 
-  su_wait_t       *sup_waits; 
-
+  /** Structure containing registration data */
+  struct su_register {
+    struct su_register *ser_next; /* Next in free list */
+    su_wakeup_f     ser_cb; 
+    su_wakeup_arg_t*ser_arg; 
+    su_root_t      *ser_root; 
+    int             ser_id; /** registration identifier */
+    su_wait_t       ser_wait[1];
+  } **sup_indices;
 };
 
 static void su_kqueue_port_decref(su_port_t *, int blocking, char const *who);
@@ -160,6 +156,8 @@
   SU_DEBUG_9(("%s(%p) called\n", "su_kqueue_port_deinit", (void *)self));
 
   su_socket_port_deinit(self->sup_base);
+
+  close(self->sup_kqueue);
 }
 
 static void su_kqueue_port_decref(su_port_t *self, int blocking, char const *who)
@@ -189,180 +187,137 @@
  *   or -1 upon an error.
  */
 int su_kqueue_port_register(su_port_t *self,
-			  su_root_t *root, 
-			  su_wait_t *wait, 
-			  su_wakeup_f callback,
-			  su_wakeup_arg_t *arg,
-			  int priority)
+			    su_root_t *root, 
+			    su_wait_t *wait, 
+			    su_wakeup_f callback,
+			    su_wakeup_arg_t *arg,
+			    int priority)
 {
   int i, j, n;
+  struct su_register *ser;
+  struct su_register **indices = self->sup_indices;
+  struct kevent ev[1];
+  int flags;
 
   assert(su_port_own_thread(self));
 
-  n = self->sup_n_waits;
+  n = self->sup_size_indices;
 
   if (n >= SU_WAIT_MAX)
     return su_seterrno(ENOMEM);
 
-  if (n >= self->sup_size_waits) {
-    su_home_t *h = self->sup_home;
-    /* Reallocate size arrays */
-    int size;
-    int *indices;
-    int *reverses;
-    su_wait_t *waits;
-    su_wakeup_f *wait_cbs;
-    su_wakeup_arg_t **wait_args;
-    su_root_t **wait_tasks;
-
-    if (self->sup_size_waits == 0)
-      size = su_root_size_hint;
-    else 
-      size = 2 * self->sup_size_waits;
-
-    if (size < SU_WAIT_MIN)
-      size = SU_WAIT_MIN;
-
-    /* Too large */
-    if (-3 - size > 0)
-      return (errno = ENOMEM), -1;
+  ser = indices[0];
+
+  if (!ser) {
+    su_home_t *h = su_port_home(self);
 
-    indices = su_realloc(h, self->sup_indices, (size + 1) * sizeof(*indices));
-    if (indices) {
+    i = self->sup_max_index, j = i == 0 ? 15 : i + 16;
+    
+    if (j >= self->sup_size_indices) {
+      /* Reallocate index table */
+      n = n < 1024 ? 2 * n : n + 1024;
+      indices = su_realloc(h, indices, n * sizeof(indices[0]));
+      if (!indices)
+	return -1;
       self->sup_indices = indices;
+      self->sup_size_indices = n;
+    }
 
-      if (self->sup_size_waits == 0)
-	indices[0] = -1;
+    /* Allocate registrations */
+    ser = su_zalloc(h, (j - i) * (sizeof *ser));
+    if (!ser)
+      return -1;
 
-      for (i = self->sup_size_waits + 1; i <= size; i++)
-	indices[i] = -1 - i;
-    }
+    indices[0] = ser;
 
-    reverses = su_realloc(h, self->sup_reverses, size * sizeof(*waits));
-    if (reverses) {
-      for (i = self->sup_size_waits; i < size; i++)
-	reverses[i] = -1;
-      self->sup_reverses = reverses;
+    for (i++; i <= j; i++) {
+      ser->ser_id = i;
+      ser->ser_next = i < j ? ser + 1 : NULL;
+      indices[i] = ser++;
     }
-      
-    waits = su_realloc(h, self->sup_waits, size * sizeof(*waits));
-    if (waits)
-      self->sup_waits = waits;
-
-    wait_cbs = su_realloc(h, self->sup_wait_cbs, size * sizeof(*wait_cbs));
-    if (wait_cbs)
-      self->sup_wait_cbs = wait_cbs;
-
-    wait_args = su_realloc(h, self->sup_wait_args, size * sizeof(*wait_args));
-    if (wait_args)
-      self->sup_wait_args = wait_args;
-
-    /* Add sup_wait_roots array, if needed */
-    wait_tasks = su_realloc(h, self->sup_wait_roots, size * sizeof(*wait_tasks));
-    if (wait_tasks) 
-      self->sup_wait_roots = wait_tasks;
 
-    if (!(indices && 
-	  reverses && waits && wait_cbs && wait_args && wait_tasks)) {
-      return -1;
-    }
+    self->sup_max_index = j;
 
-    self->sup_size_waits = size;
+    ser = indices[0];
   }
 
-  i = -self->sup_indices[0]; assert(i <= self->sup_size_waits);
+  i = ser->ser_id;
 
-  if (priority > 0) {
-    /* Insert */
-    for (n = self->sup_n_waits; n > 0; n--) {
-      j = self->sup_reverses[n-1]; assert(self->sup_indices[j] == n - 1);
-      self->sup_indices[j] = n;
-      self->sup_reverses[n] = j;
-      self->sup_waits[n] = self->sup_waits[n-1];
-      self->sup_wait_cbs[n] = self->sup_wait_cbs[n-1];
-      self->sup_wait_args[n] = self->sup_wait_args[n-1];
-      self->sup_wait_roots[n] = self->sup_wait_roots[n-1];	
-    }
-
-    self->sup_pri_offset++;
-  }
-  else {
-    /* Append - no need to move anything */
-    n = self->sup_n_waits;
+  flags = (wait->events & SU_WAIT_IN) ? EV_ADD : EV_ADD | EV_DISABLE;
+  EV_SET(ev, wait->fd, EVFILT_READ, flags, 0, 0, (void *)i);
+  if (kevent(self->sup_kqueue, ev, 1, NULL, 0, NULL) == -1) {
+    SU_DEBUG_0(("kevent((%u, %s, %u, %p)) failed: %s\n",
+		wait->fd, "EVFILT_READ", flags, (void *)i, strerror(errno)));
+    return -1;
   }
 
-  self->sup_n_waits++;
+  flags = (wait->events & SU_WAIT_OUT) ? EV_ADD : EV_ADD | EV_DISABLE;
+  EV_SET(ev, wait->fd, EVFILT_WRITE, flags, 0, 0, (void *)i);
+  if (kevent(self->sup_kqueue, ev, 1, NULL, 0, NULL) == -1) {
+    int error = errno;
+    SU_DEBUG_0(("kevent((%u, %s, %u, %p)) failed: %s\n",
+		wait->fd, "EVFILT_WRITE", flags, (void *)i, strerror(error)));
 
-  self->sup_indices[0] = self->sup_indices[i];  /* Free index */
-  self->sup_indices[i] = n;
+    EV_SET(ev, wait->fd, EVFILT_READ, EV_DELETE, 0, 0, (void *)i);
+    kevent(self->sup_kqueue, ev, 1, NULL, 0, NULL);
 
-  self->sup_reverses[n] = i;
-  self->sup_waits[n] = *wait;
-  self->sup_wait_cbs[n] = callback;
-  self->sup_wait_args[n] = arg;
-  self->sup_wait_roots[n] = root;
+    errno = error;
+    return -1;
+  }
+  indices[0] = ser->ser_next;
 
-  self->sup_registers++;
+  ser->ser_next = NULL;
+  *ser->ser_wait = *wait;
+  ser->ser_cb = callback;
+  ser->ser_arg = arg;
+  ser->ser_root = root;
 
-  /* Just like epoll, we return -1 or positive integer */
+  self->sup_registers++;
+  self->sup_n_registrations++;
 
-  return i;
+  return i;			/* return index */
 }
 
 /** Deregister a su_wait_t object. */
 static int su_kqueue_port_deregister0(su_port_t *self, int i, int destroy_wait)
 {
-  int n, N, *indices, *reverses;
+  struct su_register **indices = self->sup_indices;
+  struct su_register *ser;
+  struct kevent ev[1];
+  su_wait_t *wait;
+
+  ser = self->sup_indices[i];
+  if (ser == NULL || ser->ser_cb == NULL) {
+    su_seterrno(ENOENT);
+    return -1;
+  }
 
-  indices = self->sup_indices;
-  reverses = self->sup_reverses;
+  assert(ser->ser_id == i);
 
-  n = indices[i]; assert(n >= 0);
+  wait = ser->ser_wait;
 
-  if (destroy_wait)
-    su_wait_destroy(&self->sup_waits[n]);
-  
-  N = --self->sup_n_waits;
-  
-  if (n < self->sup_pri_offset) {
-    int j = --self->sup_pri_offset;
-    if (n != j) {
-      assert(reverses[j] > 0);
-      assert(indices[reverses[j]] == j);
-      indices[reverses[j]] = n;
-      reverses[n] = reverses[j];
-
-      self->sup_waits[n] = self->sup_waits[j];
-      self->sup_wait_cbs[n] = self->sup_wait_cbs[j];
-      self->sup_wait_args[n] = self->sup_wait_args[j];
-      self->sup_wait_roots[n] = self->sup_wait_roots[j];
-      n = j;
-    }
+  EV_SET(ev, wait->fd, EVFILT_READ, EV_DELETE, 0, 0, (void *)i);
+  if (kevent(self->sup_kqueue, ev, 1, NULL, 0, NULL) == -1) {
+    SU_DEBUG_0(("remove kevent((%u, %s, %s, %p)) failed: %s\n",
+		wait->fd, "EVFILT_READ", "EV_DELETE", (void *)i,
+		strerror(errno)));
+  }
+
+  EV_SET(ev, wait->fd, EVFILT_WRITE, EV_DELETE, 0, 0, (void *)i);
+  if (kevent(self->sup_kqueue, ev, 1, NULL, 0, NULL) == -1) {
+    SU_DEBUG_0(("remove kevent((%u, %s, %s, %p)) failed: %s\n",
+		wait->fd, "EVFILT_WRITE", "EV_DELETE", (void *)i,
+		strerror(errno)));
   }
 
-  if (n < N) {
-    assert(reverses[N] > 0);
-    assert(indices[reverses[N]] == N);
-
-    indices[reverses[N]] = n;
-    reverses[n] = reverses[N];
-
-    self->sup_waits[n] = self->sup_waits[N];
-    self->sup_wait_cbs[n] = self->sup_wait_cbs[N];
-    self->sup_wait_args[n] = self->sup_wait_args[N];
-    self->sup_wait_roots[n] = self->sup_wait_roots[N];
-    n = N;
-  }
-
-  reverses[n] = -1;
-  memset(&self->sup_waits[n], 0, sizeof self->sup_waits[n]);
-  self->sup_wait_cbs[n] = NULL;
-  self->sup_wait_args[n] = NULL;
-  self->sup_wait_roots[n] = NULL;
+  if (destroy_wait)
+    su_wait_destroy(wait);
   
-  indices[i] = indices[0];
-  indices[0] = -i;
+  memset(ser, 0, sizeof *ser);
+  ser->ser_id = i;
+  ser->ser_next = indices[0], indices[0] = ser;
 
+  self->sup_n_registrations--;
   self->sup_registers++;
 
   return i;
@@ -392,17 +347,22 @@
 			      su_wakeup_f callback, /* XXX - ignored */
 			      su_wakeup_arg_t *arg)
 {
-  int n, N;
+  int i, I;
+
+  struct su_register *ser;
 
   assert(self);
   assert(su_port_own_thread(self));
 
-  N = self->sup_n_waits;
+  I = self->sup_max_index;
 
-  for (n = 0; n < N; n++) {
-    if (SU_WAIT_CMP(wait[0], self->sup_waits[n]) == 0) {
-      return su_kqueue_port_deregister0(self, self->sup_reverses[n], 0);
-    }
+  for (i = 1; i <= I; i++) {
+    ser = self->sup_indices[i];
+
+    if (ser->ser_cb &&
+	arg == ser->ser_arg &&
+	SU_WAIT_CMP(wait[0], ser->ser_wait[0]) == 0)
+      return su_kqueue_port_deregister0(self, ser->ser_id, 0);
   }
 
   su_seterrno(ENOENT);
@@ -423,28 +383,20 @@
  */
 int su_kqueue_port_deregister(su_port_t *self, int i)
 {
-  su_wait_t wait[1] = { SU_WAIT_INIT };
-  int retval;
+  struct su_register *ser;
 
-  assert(self);
-  assert(su_port_own_thread(self));
-
-  if (i <= 0 || i > self->sup_size_waits)
+  if (i <= 0 || i > self->sup_max_index)
     return su_seterrno(EBADF);
 
-  if (self->sup_indices[i] < 0)
+  ser = self->sup_indices[i];
+  if (!ser->ser_cb)
     return su_seterrno(EBADF);
-    
-  retval = su_kqueue_port_deregister0(self, i, 1);
 
-  su_wait_destroy(wait);
-
-  return retval;
+  return su_kqueue_port_deregister0(self, i, 1);
 }
 
-
 /** @internal
- * Unregister all su_wait_t objects.
+ * Unregister all su_wait_t objects belonging to a root.
  *
  * The function su_kqueue_port_unregister_all() unregisters all su_wait_t objects
  * and destroys all queued timers associated with given root object.
@@ -457,60 +409,24 @@
 int su_kqueue_port_unregister_all(su_port_t *self, 
 				su_root_t *root)
 {
-  int i, j, index, N;
-  int             *indices, *reverses;
-  su_wait_t       *waits;
-  su_wakeup_f     *wait_cbs;
-  su_wakeup_arg_t**wait_args;
-  su_root_t      **wait_roots;
+  int i, I, n;
 
-  assert(su_port_own_thread(self));
+  struct su_register *ser;
 
-  N          = self->sup_n_waits;
-  indices    = self->sup_indices;
-  reverses   = self->sup_reverses;
-  waits      = self->sup_waits; 
-  wait_cbs   = self->sup_wait_cbs; 
-  wait_args  = self->sup_wait_args;
-  wait_roots = self->sup_wait_roots; 
-  
-  for (i = j = 0; i < N; i++) {
-    index = reverses[i]; assert(index > 0 && indices[index] == i);
+  assert(self); assert(root);
+  assert(su_port_own_thread(self));
 
-    if (wait_roots[i] == root) {
-      /* XXX - we should free all resources associated with this, too */
-      if (i < self->sup_pri_offset)
-	self->sup_pri_offset--;
+  I = self->sup_max_index;
 
-      indices[index] = indices[0];
-      indices[0] = -index;
+  for (i = 1, n = 0; i <= I; i++) {
+    ser = self->sup_indices[i];
+    if (ser->ser_root != root)
       continue;
-    }
-
-    if (i != j) {
-      indices[index] = j;
-      reverses[j]   = reverses[i];
-      waits[j]      = waits[i];
-      wait_cbs[j]   = wait_cbs[i];
-      wait_args[j]  = wait_args[i];
-      wait_roots[j] = wait_roots[i];
-    }
-    
-    j++;
+    su_kqueue_port_deregister0(self, ser->ser_id, 0);
+    n++;
   }
-  
-  for (i = j; i < N; i++) {
-    reverses[i] = -1;
-    wait_cbs[i] = NULL;
-    wait_args[i] = NULL;
-    wait_roots[i] = NULL;
-  }
-  memset(&waits[j], 0, (char *)&waits[N] - (char *)&waits[j]);
-
-  self->sup_n_waits = j;
-  self->sup_registers++;
 
-  return N - j;
+  return n;
 }
 
 /**Set mask for a registered event. @internal
@@ -528,17 +444,43 @@
  */
 int su_kqueue_port_eventmask(su_port_t *self, int index, int socket, int events)
 {
-  int n;
-  assert(self);
-  assert(su_port_own_thread(self));
+  struct su_register *ser;
+  struct kevent ev[1];
+  su_wait_t *wait;
+  int flags;
 
-  if (index <= 0 || index > self->sup_size_waits)
+  if (index <= 0 || index > self->sup_max_index)
     return su_seterrno(EBADF);
-  n = self->sup_indices[index];
-  if (n < 0)
+
+  ser = self->sup_indices[index];
+  if (!ser->ser_cb)
     return su_seterrno(EBADF);
 
-  return su_wait_mask(&self->sup_waits[n], socket, events);
+  wait = ser->ser_wait;
+
+  assert(socket == wait->fd);
+
+  wait->events = events;
+
+  flags = (wait->events & SU_WAIT_IN) ? EV_ADD | EV_ENABLE : EV_ADD | EV_DISABLE;
+  EV_SET(ev, wait->fd, EVFILT_READ, flags, 0, 0, (void *)index);
+  if (kevent(self->sup_kqueue, ev, 1, NULL, 0, NULL) == -1) {
+    SU_DEBUG_0(("modify kevent((%u, %s, %s, %p)) failed: %s\n",
+		wait->fd, "EVFILT_READ",
+		(events & SU_WAIT_IN) ? "EV_ENABLE" : "EV_DISABLE",
+		(void *)index, strerror(errno)));
+  }
+
+  flags = (wait->events & SU_WAIT_OUT) ? EV_ADD | EV_ENABLE : EV_ADD | EV_DISABLE;
+  EV_SET(ev, wait->fd, EVFILT_WRITE, flags, 0, 0, (void *)index);
+  if (kevent(self->sup_kqueue, ev, 1, NULL, 0, NULL) == -1) {
+    SU_DEBUG_0(("modify kevent((%u, %s, %s, %p)) failed: %s\n",
+		wait->fd, "EVFILT_WRITE",
+		(events & SU_WAIT_OUT) ? "EV_ENABLE" : "EV_DISABLE",
+		(void *)index, strerror(errno)));
+  }
+
+  return 0;
 }
 
 /** @internal Enable multishot mode.
@@ -578,108 +520,94 @@
 static
 int su_kqueue_port_wait_events(su_port_t *self, su_duration_t tout)
 {
-  int i, j, events = 0;
-  su_wait_t *waits = self->sup_waits;
-  int n = self->sup_n_waits;
-  su_root_t *root;
+  int j, n, events = 0, index;
   unsigned version = self->sup_registers;
-  struct timespec timeout[1] = {{ 0 }};
 
-  timeout->tv_nsec = tout;
+  int const M = 4;
+  struct kevent ev[M];
+  
+  struct timespec ts;
 
-  i = kevent(self->sup_kqueue,
-	     self->sup_waits, n, /* Active waits */
-	     self->sup_waits, self->sup_size_waits, /* Total waits */
-	     timeout);
-
-  if (i >= 0 && i < n) {
-    /* kqueue() can return events for multiple wait objects */
-    if (self->sup_multishot) {
-      for (j = 0; j < i; j++) {
-        if (self->sup_waits[j].filter == EVFILT_READ ||
-	    self->sup_waits[j].filter == EVFILT_WRITE) {
-          root = self->sup_wait_roots[i];
-          self->sup_wait_cbs[i](root ? su_root_magic(root) : NULL,
-                                &waits[i],
-                                self->sup_wait_args[i]);
-          events++;
-          /* Callback function used su_register()/su_deregister() */
-          if (version != self->sup_registers)
-            break;
-        }
-      }
-    }
-    else {
-      root = self->sup_wait_roots[i];
-      self->sup_wait_cbs[i](root ? su_root_magic(root) : NULL,
-                            &self->sup_waits[i],
-                            self->sup_wait_args[i]);
+  ts.tv_sec = tout / 1000;
+  ts.tv_nsec = tout % 1000 * 1000000;
+
+  n = kevent(self->sup_kqueue, NULL, 0,
+	     ev, self->sup_multishot ? M : 1,
+	     tout < SU_DURATION_MAX ? &ts : NULL);
+
+  assert(n <= M);
+  
+  for (j = 0; j < n; j++) {
+    struct su_register *ser;
+    su_root_magic_t *magic;
+
+    index = (int)ev[j].udata;
+    if (index <= 0 || self->sup_max_index < index)
+      continue;
+    ser = self->sup_indices[index];
+
+    magic = ser->ser_root ? su_root_magic(ser->ser_root) : NULL;
+    ser->ser_wait->revents =
+      (ser->ser_wait->events | SU_WAIT_HUP) &
+      (
+       ((ev[j].filter == EVFILT_READ) ? SU_WAIT_IN : 0) |
+       ((ev[j].filter == EVFILT_WRITE) ? SU_WAIT_OUT : 0) |
+       ((ev[j].flags & EV_EOF) ? SU_WAIT_HUP : 0)
+       );
+    if (ser->ser_wait->revents) {
+      ser->ser_cb(magic, ser->ser_wait, ser->ser_arg);
       events++;
+      if (version != self->sup_registers)
+	/* Callback function used su_register()/su_deregister() */
+	return events;
     }
-  }
+  }    
 
-  return events;
+  return n;
 }
 
-#if 0
-/** @internal
- *  Prints out the contents of the port.
- *
- * @param self pointer to a port
- * @param f    pointer to a file (if @c NULL, uses @c stdout).
- */
-void su_port_dump(su_port_t const *self, FILE *f)
-{
-  int i;
-#define IS_WAIT_IN(x) (((x)->events & SU_WAIT_IN) ? "IN" : "")
-#define IS_WAIT_OUT(x) (((x)->events & SU_WAIT_OUT) ? "OUT" : "")
-#define IS_WAIT_ACCEPT(x) (((x)->events & SU_WAIT_ACCEPT) ? "ACCEPT" : "")
-
-  if (f == NULL)
-    f = stdout;
-
-  fprintf(f, "su_port_t at %p:\n", self);
-  fprintf(f, "\tport is%s running\n", self->sup_running ? "" : "not ");
-#if SU_HAVE_PTHREADS
-  fprintf(f, "\tport tid %p\n", (void *)self->sup_tid);
-  fprintf(f, "\tport mbox %d (%s%s%s)\n", self->sup_mbox[0],
-	  IS_WAIT_IN(&self->sup_mbox_wait),
-	  IS_WAIT_OUT(&self->sup_mbox_wait),
-	  IS_WAIT_ACCEPT(&self->sup_mbox_wait));
-#endif
-  fprintf(f, "\t%d wait objects\n", self->sup_n_waits);
-  for (i = 0; i < self->sup_n_waits; i++) {
-    
-  }
-}
-
-#endif
 
-/** Create a port using poll() or kqueue().
+/** Create a port using kqueue() (or poll()/select(), if kqueue() fails).
  */
 su_port_t *su_kqueue_port_create(void)
 {
-  int kq = kqueue();
   su_port_t *self = NULL;
+  int kq = kqueue();
 
-  if (kq < 0);
-  return self;
+  if (kq < 0) {
+#if HAVE_POLL
+    return su_poll_port_create();
+#else
+    return su_select_port_create();
+#endif
+  }
 
   self = su_home_new(sizeof *self);
   if (!self)
-    return self;
+    goto failed;
 
   if (su_home_destructor(su_port_home(self), su_kqueue_port_deinit) < 0)
-    return su_home_unref(su_port_home(self)), NULL;
+    goto failed;
 
-  self->sup_multishot = SU_ENABLE_MULTISHOT_KQUEUE;
+  self->sup_kqueue = kq, kq = -1;
+  self->sup_indices = su_zalloc(su_port_home(self),
+				(sizeof self->sup_indices[0]) * 
+				(self->sup_size_indices = 64));
+  if (!self->sup_indices)
+    goto failed;
 
   if (su_socket_port_init(self->sup_base, su_kqueue_port_vtable) < 0)
-    return su_home_unref(su_port_home(self)), NULL;
+    goto failed;
 
-  self->sup_kqueue = kq;
+  self->sup_multishot = SU_ENABLE_MULTISHOT_KQUEUE;
 
   return self;
+
+ failed:
+  if (kq != -1)
+    close(kq);
+  su_home_unref(su_port_home(self));
+  return NULL;
 }
 
 int su_kqueue_clone_start(su_root_t *parent,
@@ -688,7 +616,7 @@
 			su_root_init_f init,
 			su_root_deinit_f deinit)
 {
-  return su_pthreaded_port_start(su_default_port_create, 
+  return su_pthreaded_port_start(su_kqueue_port_create, 
 				 parent, return_clone, magic, init, deinit);
 }
 
@@ -709,4 +637,3 @@
 }
 
 #endif  /* HAVE_KQUEUE */
-

Modified: freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/su/test_htable.c
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/su/test_htable.c	(original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/su/test_htable.c	Thu Mar 22 10:41:43 2007
@@ -181,44 +181,46 @@
 
   BEGIN();
 
-  TEST0(c = context_create());
-  TEST0(add(c, 0, 1)); TEST0(c->c_hash->ht_table[0]);
-  TEST0(add(c, 1, 2)); TEST0(c->c_hash->ht_table[1]);
-  TEST0(add(c, 2, 3)); TEST0(c->c_hash->ht_table[2]);
-  TEST0(add(c, 0, 4)); TEST0(c->c_hash->ht_table[3]);
-  TEST0(add(c, 2, 5)); TEST0(c->c_hash->ht_table[4]);
-
-  TEST0(e = search(c, 1, 2, 0));
-  zap(c, e);
-  TEST0(c->c_hash->ht_table[0]);
-  TEST0(c->c_hash->ht_table[1]);
-  TEST0(c->c_hash->ht_table[2]);
-  TEST0(c->c_hash->ht_table[3]);
-  TEST0(c->c_hash->ht_table[4] == NULL);
+  TEST_1(c = context_create());
+  TEST_1(add(c, 0, 1)); TEST_1(c->c_hash->ht_table[0]);
+  TEST_1(add(c, 1, 2)); TEST_1(c->c_hash->ht_table[1]);
+  TEST_1(add(c, 2, 3)); TEST_1(c->c_hash->ht_table[2]);
+  TEST_1(add(c, 0, 4)); TEST_1(c->c_hash->ht_table[3]);
+  TEST_1(add(c, 2, 5)); TEST_1(c->c_hash->ht_table[4]);
+
+  TEST_1(e = search(c, 1, 2, 0));
+  TEST(htable_remove(c->c_hash, e), 0);
+  TEST(htable_remove(c->c_hash, e), -1);
+  su_free(c->c_home, e);
+  TEST_1(c->c_hash->ht_table[0]);
+  TEST_1(c->c_hash->ht_table[1]);
+  TEST_1(c->c_hash->ht_table[2]);
+  TEST_1(c->c_hash->ht_table[3]);
+  TEST_1(c->c_hash->ht_table[4] == NULL);
 
   zap(c, c->c_hash->ht_table[0]);
 
-  TEST0(c->c_hash->ht_table[0]);
-  TEST0(c->c_hash->ht_table[1] == NULL);
-  TEST0(c->c_hash->ht_table[2]);
-  TEST0(c->c_hash->ht_table[3]);
-  TEST0(c->c_hash->ht_table[4] == NULL);
+  TEST_1(c->c_hash->ht_table[0]);
+  TEST_1(c->c_hash->ht_table[1] == NULL);
+  TEST_1(c->c_hash->ht_table[2]);
+  TEST_1(c->c_hash->ht_table[3]);
+  TEST_1(c->c_hash->ht_table[4] == NULL);
 
-  TEST0(add(c, 0, 6)); TEST0(c->c_hash->ht_table[1]);
-  TEST0(add(c, 1, 7)); TEST0(c->c_hash->ht_table[4]);
+  TEST_1(add(c, 0, 6)); TEST_1(c->c_hash->ht_table[1]);
+  TEST_1(add(c, 1, 7)); TEST_1(c->c_hash->ht_table[4]);
 
   /* Test that zapping entry 0 does not move 2 and 3 */
   zap(c, c->c_hash->ht_table[0]);
-  TEST0(c->c_hash->ht_table[4] == NULL);
+  TEST_1(c->c_hash->ht_table[4] == NULL);
 
   {
     /* Insert entries at the end of hash, then resize and check
        for correct ordering */
     hash_value_t size = c->c_hash->ht_size, h = size - 1;
 
-    TEST0(add(c, h, 0)); TEST0(add(c, h, 1)); TEST0(add(c, h, 2));
-    TEST0(add(c, h, 3)); TEST0(add(c, h, 4)); TEST0(add(c, h, 5));
-    TEST0(add(c, h, 6)); TEST0(add(c, h, 7)); TEST0(add(c, h, 8));
+    TEST_1(add(c, h, 0)); TEST_1(add(c, h, 1)); TEST_1(add(c, h, 2));
+    TEST_1(add(c, h, 3)); TEST_1(add(c, h, 4)); TEST_1(add(c, h, 5));
+    TEST_1(add(c, h, 6)); TEST_1(add(c, h, 7)); TEST_1(add(c, h, 8));
 
     TEST(count(c, h), 9);
     

Modified: freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/su/test_memmem.c
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/su/test_memmem.c	(original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/su/test_memmem.c	Thu Mar 22 10:41:43 2007
@@ -78,14 +78,25 @@
 
   TEST_P(memmem(haystack, 12, needle, 3), haystack + 2);
   TEST_P(memmem(needle, 3, haystack, 12), NULL);
-  TEST_P(memmem(haystack, 12, "", 0), haystack);
-  TEST_P(memmem(haystack, 12, null, 0), haystack);
-  TEST_P(memmem(haystack, 0, "", 0), haystack);
-  TEST_P(memmem(haystack, 0, null, 0), haystack);
+  
+#if HAVE_MEMMEM
+  if (memmem(haystack, 12, "", 0) == NULL) {
+    fprintf(stderr, "test_memmem.c: "
+	    "*** WARNING: system memmem() fails with empty needle ***\n");
+  }
+  else 
+#endif
+  {
+    TEST_P(memmem(haystack, 12, "", 0), haystack);
+    TEST_P(memmem(haystack, 12, null, 0), haystack);
+    TEST_P(memmem(haystack, 0, "", 0), haystack);
+    TEST_P(memmem(haystack, 0, null, 0), haystack);
+  }
 
   TEST_P(memmem(haystack + 2, 3, needle, 3), haystack + 2);
   TEST_P(memmem(haystack + 2, 2, needle, 3), NULL);
   TEST_P(memmem(a = "a\0bc", 4, "a\0bc", 4), a);
+  TEST_P(memmem(a, 4, "\0bc", 3), a + 1);
 
   END();
 }

Modified: freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/m4/sac-tport.m4
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/m4/sac-tport.m4	(original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/m4/sac-tport.m4	Thu Mar 22 10:41:43 2007
@@ -27,7 +27,9 @@
 AC_SYS_IP_RECVERR
 AC_SYS_IPV6_RECVERR
 
-AC_CHECK_HEADERS(netinet/tcp.h netinet/sctp.h)
+AC_CHECK_HEADERS([netinet/tcp.h netinet/sctp.h],[],[],[
+#include <sys/socket.h>
+])
 
 AC_ARG_ENABLE(sctp,
 [  --enable-sctp           use SCTP [[disabled]]],,



More information about the Freeswitch-branches mailing list