[commit] r4729 - in freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip: . libsofia-sip-ua/su libsofia-sip-ua/su/sofia-sip m4
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@nokia.com> * Makefile.am, m4/sac-tport.m4: fixes for Solaris Wed Mar 21 06:40:04 EDT 2007 Pekka Pessi <first.lastname@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@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@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@nokia.com> + * @author Pekka Pessi <Pekka.Pessi@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]]],,
participants (1)
-
Freeswitch SVN