[Freeswitch-svn] [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-svn
mailing list