* #36737: switch back to svn repo, remove assert in sip_transaction.c
diff --git a/jni/pjproject-android/.svn/pristine/d1/d1e132d4872919b50761582e88afc6aec7d210bb.svn-base b/jni/pjproject-android/.svn/pristine/d1/d1e132d4872919b50761582e88afc6aec7d210bb.svn-base
new file mode 100644
index 0000000..c1c5ca2
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/d1/d1e132d4872919b50761582e88afc6aec7d210bb.svn-base
@@ -0,0 +1,698 @@
+/* $Id$ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#include <pj/os.h>
+#include <pj/assert.h>
+#include <pj/pool.h>
+#include <pj/log.h>
+#include <pj/except.h>
+#include <pj/errno.h>
+#include <pj/string.h>
+#include <pj/compat/high_precision.h>
+#include <pj/compat/sprintf.h>
+
+#include <linux/config.h>
+#include <linux/version.h>
+#if defined(MODVERSIONS)
+#include <linux/modversions.h>
+#endif
+#include <linux/kernel.h>
+#include <linux/sched.h>
+//#include <linux/tqueue.h>
+#include <linux/wait.h>
+#include <linux/signal.h>
+
+#include <asm/atomic.h>
+#include <asm/unistd.h>
+#include <asm/semaphore.h>
+
+#define THIS_FILE   "oslinuxkern"
+
+struct pj_thread_t
+{
+    /** Thread's name. */
+    char obj_name[PJ_MAX_OBJ_NAME];
+
+    /** Linux task structure for thread. */
+    struct task_struct *thread;	
+
+    /** Flags (specified in pj_thread_create) */
+    unsigned flags;
+
+    /** Task queue needed to launch thread. */
+    //struct tq_struct	tq;	
+
+    /** Semaphore needed to control thread startup. */
+    struct semaphore	startstop_sem;
+
+    /** Semaphore to suspend thread during startup. */
+    struct semaphore	suspend_sem;
+
+    /** Queue thread is waiting on. Gets initialized by
+        thread_initialize, can be used by thread itself.
+     */
+    wait_queue_head_t	queue;
+
+    /** Flag to tell thread whether to die or not.
+        When the thread receives a signal, it must check
+        the value of terminate and call thread_deinitialize and terminate
+        if set.
+     */
+    int terminate;    
+
+    /** Thread's entry. */
+    pj_thread_proc *func;
+
+    /** Argument. */
+    void *arg;
+};
+
+struct pj_atomic_t
+{
+    atomic_t atom;
+};
+
+struct pj_mutex_t
+{
+    struct semaphore sem;
+    pj_bool_t	     recursive;
+    pj_thread_t	    *owner;
+    int		     own_count;
+};
+
+struct pj_sem_t
+{
+    struct semaphore sem;
+};
+
+/*
+ * Static global variables.
+ */
+#define MAX_TLS_ID  32
+static void *tls_values[MAX_TLS_ID];
+static int tls_id;
+static long thread_tls_id;
+static spinlock_t critical_section = SPIN_LOCK_UNLOCKED;
+static unsigned long spinlock_flags;
+static pj_thread_t main_thread;
+
+/* private functions */
+//#define TRACE_(expr)	PJ_LOG(3,expr)
+#define TRACE_(x)
+
+
+/* This must be called in the context of the new thread. */
+static void thread_initialize( pj_thread_t *thread )
+{
+    TRACE_((THIS_FILE, "---new thread initializing..."));
+
+    /* Set TLS */
+    pj_thread_local_set(thread_tls_id, thread);
+
+    /* fill in thread structure */
+    thread->thread = current;
+    pj_assert(thread->thread != NULL);
+
+    /* set signal mask to what we want to respond */
+    siginitsetinv(&current->blocked, 
+		  sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGTERM));
+
+    /* initialise wait queue */
+    init_waitqueue_head(&thread->queue);
+
+    /* initialise termination flag */
+    thread->terminate = 0;
+
+    /* set name of this process (making sure obj_name is null 
+     * terminated first) 
+     */
+    thread->obj_name[PJ_MAX_OBJ_NAME-1] = '\0';
+    sprintf(current->comm, thread->obj_name);
+        
+    /* tell the creator that we are ready and let him continue */
+    up(&thread->startstop_sem);	
+}
+
+/* cleanup of thread. Called by the exiting thread. */
+static void thread_deinitialize(pj_thread_t *thread)
+{
+    /* we are terminating */
+
+    /* lock the kernel, the exit will unlock it */
+    thread->thread = NULL;
+    mb();
+
+    /* notify the stop_kthread() routine that we are terminating. */
+    up(&thread->startstop_sem);
+
+    /* the kernel_thread that called clone() does a do_exit here. */
+
+    /* there is no race here between execution of the "killer" and 
+       real termination of the thread (race window between up and do_exit), 
+       since both the thread and the "killer" function are running with 
+       the kernel lock held.
+       The kernel lock will be freed after the thread exited, so the code
+       is really not executed anymore as soon as the unload functions gets
+       the kernel lock back.
+       The init process may not have made the cleanup of the process here,
+       but the cleanup can be done safely with the module unloaded.
+    */
+
+}
+
+static int thread_proc(void *arg)
+{
+    pj_thread_t *thread = arg;
+
+    TRACE_((THIS_FILE, "---new thread starting!"));
+
+    /* Initialize thread. */
+    thread_initialize( thread );
+
+    /* Wait if created suspended. */
+    if (thread->flags & PJ_THREAD_SUSPENDED) {
+	TRACE_((THIS_FILE, "---new thread suspended..."));
+	down(&thread->suspend_sem);
+    }
+
+    TRACE_((THIS_FILE, "---new thread running..."));
+
+    pj_assert(thread->func != NULL);
+
+    /* Call thread's entry. */
+    (*thread->func)(thread->arg);
+
+    TRACE_((THIS_FILE, "---thread exiting..."));
+
+    /* Cleanup thread. */
+    thread_deinitialize(thread);
+
+    return 0;
+}
+
+/* The very task entry. */
+static void kthread_launcher(void *arg)
+{
+    TRACE_((THIS_FILE, "...launching thread!..."));
+    kernel_thread(&thread_proc, arg, 0);
+}
+
+PJ_DEF(pj_status_t) pj_init(void)
+{
+    pj_status_t rc;
+
+    PJ_LOG(5, ("pj_init", "Initializing PJ Library.."));
+
+    rc = pj_thread_init();
+    if (rc != PJ_SUCCESS)
+	return rc;
+
+    /* Initialize exception ID for the pool. 
+     * Must do so after critical section is configured.
+     */
+    rc = pj_exception_id_alloc("PJLIB/No memory", &PJ_NO_MEMORY_EXCEPTION);
+    if (rc != PJ_SUCCESS)
+        return rc;
+
+    return PJ_SUCCESS;
+}
+
+PJ_DEF(pj_uint32_t) pj_getpid(void)
+{
+    return 1;
+}
+
+PJ_DEF(pj_status_t) pj_thread_register ( const char *cstr_thread_name,
+					 pj_thread_desc desc,
+					 pj_thread_t **ptr_thread)
+{
+    char stack_ptr;
+    pj_thread_t *thread = (pj_thread_t *)desc;
+    pj_str_t thread_name = pj_str((char*)cstr_thread_name);
+
+    /* Size sanity check. */
+    if (sizeof(pj_thread_desc) < sizeof(pj_thread_t)) {
+	pj_assert(!"Not enough pj_thread_desc size!");
+	return PJ_EBUG;
+    }
+
+    /* If a thread descriptor has been registered before, just return it. */
+    if (pj_thread_local_get (thread_tls_id) != 0) {
+	// 2006-02-26 bennylp:
+	//  This wouldn't work in all cases!.
+	//  If thread is created by external module (e.g. sound thread),
+	//  thread may be reused while the pool used for the thread descriptor
+	//  has been deleted by application.
+	//*thread_ptr = (pj_thread_t*)pj_thread_local_get (thread_tls_id);
+        //return PJ_SUCCESS;
+    }
+
+    /* Initialize and set the thread entry. */
+    pj_bzero(desc, sizeof(struct pj_thread_t));
+
+    if(cstr_thread_name && pj_strlen(&thread_name) < sizeof(thread->obj_name)-1)
+	pj_sprintf(thread->obj_name, cstr_thread_name, thread->thread);
+    else
+	pj_snprintf(thread->obj_name, sizeof(thread->obj_name), 
+		    "thr%p", (void*)thread->thread);
+    
+    /* Initialize. */
+    thread_initialize(thread);
+
+    /* Eat semaphore. */
+    down(&thread->startstop_sem);
+
+#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0
+    thread->stk_start = &stack_ptr;
+    thread->stk_size = 0xFFFFFFFFUL;
+    thread->stk_max_usage = 0;
+#else
+    stack_ptr = '\0';
+#endif
+
+    *ptr_thread = thread;
+    return PJ_SUCCESS;
+}
+
+
+pj_status_t pj_thread_init(void)
+{
+    pj_status_t rc;
+    pj_thread_t *dummy;
+    
+    rc = pj_thread_local_alloc(&thread_tls_id);
+    if (rc != PJ_SUCCESS)
+	return rc;
+
+    return pj_thread_register("pjlib-main", (long*)&main_thread, &dummy);
+}
+
+PJ_DEF(pj_status_t) pj_thread_create( pj_pool_t *pool, const char *thread_name,
+				      pj_thread_proc *proc, void *arg,
+				      pj_size_t stack_size, unsigned flags,
+				      pj_thread_t **ptr_thread)
+{
+    pj_thread_t *thread;
+
+    TRACE_((THIS_FILE, "pj_thread_create()"));
+    
+    PJ_ASSERT_RETURN(pool && proc && ptr_thread, PJ_EINVAL);
+
+    thread = pj_pool_zalloc(pool, sizeof(pj_thread_t));
+    if (!thread)
+	return PJ_ENOMEM;
+
+    PJ_UNUSED_ARG(stack_size);
+
+    /* Thread name. */
+    if (!thread_name) 
+	thread_name = "thr%p";
+    
+    if (strchr(thread_name, '%')) {
+	pj_snprintf(thread->obj_name, PJ_MAX_OBJ_NAME, thread_name, thread);
+    } else {
+	strncpy(thread->obj_name, thread_name, PJ_MAX_OBJ_NAME);
+	thread->obj_name[PJ_MAX_OBJ_NAME-1] = '\0';
+    }
+    
+    /* Init thread's semaphore. */
+    TRACE_((THIS_FILE, "...init semaphores..."));
+    init_MUTEX_LOCKED(&thread->startstop_sem);
+    init_MUTEX_LOCKED(&thread->suspend_sem);
+
+    thread->flags = flags;
+
+    if ((flags & PJ_THREAD_SUSPENDED) == 0) {
+	up(&thread->suspend_sem);
+    }
+
+    /* Store the functions and argument. */
+    thread->func = proc;
+    thread->arg = arg;
+    
+    /* Save return value. */
+    *ptr_thread = thread;
+    
+    /* Create the new thread by running a task through keventd. */
+
+#if 0
+    /* Initialize the task queue struct. */
+    thread->tq.sync = 0;
+    INIT_LIST_HEAD(&thread->tq.list);
+    thread->tq.routine = kthread_launcher;
+    thread->tq.data = thread;
+
+    /* and schedule it for execution. */
+    schedule_task(&thread->tq);
+#endif
+    kthread_launcher(thread);
+
+    /* Wait until thread has reached the setup_thread routine. */
+    TRACE_((THIS_FILE, "...wait for the new thread..."));
+    down(&thread->startstop_sem);
+
+    TRACE_((THIS_FILE, "...main thread resumed..."));
+    return PJ_SUCCESS;
+}
+
+PJ_DEF(const char*) pj_thread_get_name(pj_thread_t *thread)
+{
+    return thread->obj_name;
+}
+
+PJ_DEF(pj_status_t) pj_thread_resume(pj_thread_t *thread)
+{
+    up(&thread->suspend_sem);
+    return PJ_SUCCESS;
+}
+
+PJ_DEF(pj_thread_t*) pj_thread_this(void)
+{
+    return (pj_thread_t*)pj_thread_local_get(thread_tls_id);
+}
+
+PJ_DEF(pj_status_t) pj_thread_join(pj_thread_t *p)
+{
+    TRACE_((THIS_FILE, "pj_thread_join()"));
+    down(&p->startstop_sem);
+    TRACE_((THIS_FILE, "  joined!"));
+    return PJ_SUCCESS;
+}
+
+PJ_DEF(pj_status_t) pj_thread_destroy(pj_thread_t *thread)
+{
+    PJ_ASSERT_RETURN(thread != NULL, PJ_EINVALIDOP);
+    return PJ_SUCCESS;
+}
+
+PJ_DEF(pj_status_t) pj_thread_sleep(unsigned msec)
+{
+    pj_highprec_t ticks;
+    pj_thread_t *thread = pj_thread_this();
+
+    PJ_ASSERT_RETURN(thread != NULL, PJ_EBUG);
+    
+    /* Use high precision calculation to make sure we don't
+     * crop values:
+     *
+     *	ticks = HZ * msec / 1000
+     */
+    ticks = HZ;
+    pj_highprec_mul(ticks, msec);
+    pj_highprec_div(ticks, 1000);
+
+    TRACE_((THIS_FILE, "this thread will sleep for %u ticks", ticks));
+    interruptible_sleep_on_timeout( &thread->queue, ticks);
+    return PJ_SUCCESS;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+PJ_DEF(pj_status_t) pj_atomic_create( pj_pool_t *pool, 
+				      pj_atomic_value_t value,
+				      pj_atomic_t **ptr_var)
+{
+    pj_atomic_t *t = pj_pool_calloc(pool, 1, sizeof(pj_atomic_t));
+    if (!t) return PJ_ENOMEM;
+
+    atomic_set(&t->atom, value);
+    *ptr_var = t;
+    
+    return PJ_SUCCESS;
+}
+
+PJ_DEF(pj_status_t) pj_atomic_destroy( pj_atomic_t *var )
+{
+    return PJ_SUCCESS;
+}
+
+PJ_DEF(void) pj_atomic_set(pj_atomic_t *var, pj_atomic_value_t value)
+{
+    atomic_set(&var->atom, value);
+}
+
+PJ_DEF(pj_atomic_value_t) pj_atomic_get(pj_atomic_t *var)
+{
+    return atomic_read(&var->atom);
+}
+
+PJ_DEF(void) pj_atomic_inc(pj_atomic_t *var)
+{
+    atomic_inc(&var->atom);
+}
+
+PJ_DEF(void) pj_atomic_dec(pj_atomic_t *var)
+{
+    atomic_dec(&var->atom);
+}
+
+PJ_DEF(void) pj_atomic_add( pj_atomic_t *var, pj_atomic_value_t value )
+{
+    atomic_add(value, &var->atom);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+PJ_DEF(pj_status_t) pj_thread_local_alloc(long *index)
+{
+    if (tls_id >= MAX_TLS_ID)
+	return PJ_ETOOMANY;
+    
+    *index = tls_id++;
+
+    return PJ_SUCCESS;
+}
+
+PJ_DEF(void) pj_thread_local_free(long index)
+{
+    pj_assert(index >= 0 && index < MAX_TLS_ID);
+}
+
+PJ_DEF(pj_status_t) pj_thread_local_set(long index, void *value)
+{
+    pj_assert(index >= 0 && index < MAX_TLS_ID);
+    tls_values[index] = value;
+    return PJ_SUCCESS;
+}
+
+PJ_DEF(void*) pj_thread_local_get(long index)
+{
+    pj_assert(index >= 0 && index < MAX_TLS_ID);
+    return tls_values[index];
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+PJ_DEF(void) pj_enter_critical_section(void)
+{
+    spin_lock_irqsave(&critical_section, spinlock_flags);
+}
+
+PJ_DEF(void) pj_leave_critical_section(void)
+{
+    spin_unlock_irqrestore(&critical_section, spinlock_flags);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+PJ_DEF(pj_status_t) pj_mutex_create( pj_pool_t *pool, 
+				     const char *name, 
+				     int type,
+				     pj_mutex_t **ptr_mutex)
+{
+    pj_mutex_t *mutex;
+    
+    PJ_UNUSED_ARG(name);
+
+    mutex = pj_pool_alloc(pool, sizeof(pj_mutex_t));
+    if (!mutex)
+	return PJ_ENOMEM;
+
+    init_MUTEX(&mutex->sem);
+
+    mutex->recursive = (type == PJ_MUTEX_RECURSE);
+    mutex->owner = NULL;
+    mutex->own_count = 0;
+    
+    /* Done. */
+    *ptr_mutex = mutex;
+    return PJ_SUCCESS;
+}
+
+PJ_DEF(pj_status_t) pj_mutex_create_simple( pj_pool_t *pool, const char *name,
+					    pj_mutex_t **mutex )
+{
+    return pj_mutex_create(pool, name, PJ_MUTEX_SIMPLE, mutex);
+}
+
+PJ_DEF(pj_status_t) pj_mutex_create_recursive( pj_pool_t *pool,
+					       const char *name,
+					       pj_mutex_t **mutex )
+{
+    return pj_mutex_create( pool, name, PJ_MUTEX_RECURSE, mutex);
+}
+
+PJ_DEF(pj_status_t) pj_mutex_lock(pj_mutex_t *mutex)
+{
+    PJ_ASSERT_RETURN(mutex, PJ_EINVAL);
+
+    if (mutex->recursive) {
+	pj_thread_t *this_thread = pj_thread_this();
+	if (mutex->owner == this_thread) {
+	    ++mutex->own_count;
+	} else {
+	    down(&mutex->sem);
+	    pj_assert(mutex->own_count == 0);
+	    mutex->owner = this_thread;
+	    mutex->own_count = 1;
+	}
+    } else {
+	down(&mutex->sem);
+    }
+    return PJ_SUCCESS;
+}
+
+PJ_DEF(pj_status_t) pj_mutex_trylock(pj_mutex_t *mutex)
+{
+    long rc;
+
+    PJ_ASSERT_RETURN(mutex, PJ_EINVAL);
+
+    if (mutex->recursive) {
+	pj_thread_t *this_thread = pj_thread_this();
+	if (mutex->owner == this_thread) {
+	    ++mutex->own_count;
+	} else {
+	    rc = down_interruptible(&mutex->sem);
+	    if (rc != 0)
+		return PJ_RETURN_OS_ERROR(-rc);
+	    pj_assert(mutex->own_count == 0);
+	    mutex->owner = this_thread;
+	    mutex->own_count = 1;
+	}
+    } else {
+	int rc = down_trylock(&mutex->sem);
+	if (rc != 0)
+	    return PJ_RETURN_OS_ERROR(-rc);
+    }
+    return PJ_SUCCESS;
+}
+
+PJ_DEF(pj_status_t) pj_mutex_unlock(pj_mutex_t *mutex)
+{
+    PJ_ASSERT_RETURN(mutex, PJ_EINVAL);
+
+    if (mutex->recursive) {
+	pj_thread_t *this_thread = pj_thread_this();
+	if (mutex->owner == this_thread) {
+	    pj_assert(mutex->own_count > 0);
+	    --mutex->own_count;
+	    if (mutex->own_count == 0) {
+		mutex->owner = NULL;
+		up(&mutex->sem);
+	    }
+	} else {
+	    pj_assert(!"Not owner!");
+	    return PJ_EINVALIDOP;
+	}
+    } else {
+	up(&mutex->sem);
+    }
+    return PJ_SUCCESS;
+}
+
+PJ_DEF(pj_status_t) pj_mutex_destroy(pj_mutex_t *mutex)
+{
+    PJ_ASSERT_RETURN(mutex != NULL, PJ_EINVAL);
+
+    return PJ_SUCCESS;
+}
+
+#if defined(PJ_DEBUG) && PJ_DEBUG != 0
+PJ_DEF(pj_bool_t) pj_mutex_is_locked(pj_mutex_t *mutex)
+{
+    if (mutex->recursive)
+	return mutex->owner == pj_thread_this();
+    else
+	return 1;
+}
+#endif	/* PJ_DEBUG */
+
+
+#if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0
+
+PJ_DEF(pj_status_t) pj_sem_create(  pj_pool_t *pool, 
+                                    const char *name,
+				    unsigned initial, 
+                                    unsigned max,
+				    pj_sem_t **sem)
+{
+    pj_sem_t *sem;
+
+    PJ_UNUSED_ARG(max);
+
+    PJ_ASSERT_RETURN(pool && sem, PJ_EINVAL);
+    
+    sem = pj_pool_alloc(pool, sizeof(pj_sem_t));
+    sema_init(&sem->sem, initial);
+    return PJ_SUCCESS;
+}
+
+PJ_DEF(pj_status_t) pj_sem_wait(pj_sem_t *sem)
+{
+    PJ_ASSERT_RETURN(pool && sem, PJ_EINVAL);
+
+    down(&sem->sem);
+    return PJ_SUCCESS;
+}
+
+PJ_DEF(pj_status_t) pj_sem_trywait(pj_sem_t *sem)
+{
+    int rc;
+
+    PJ_ASSERT_RETURN(pool && sem, PJ_EINVAL);
+
+    rc = down_trylock(&sem->sem);
+    if (rc != 0) {
+	return PJ_RETURN_OS_ERROR(-rc);
+    } else {
+	return PJ_SUCCESS;
+    }
+}
+
+PJ_DEF(pj_status_t) pj_sem_post(pj_sem_t *sem)
+{
+    PJ_ASSERT_RETURN(pool && sem, PJ_EINVAL);
+
+    up(&sem->sem);
+    return PJ_SUCCESS;
+}
+
+PJ_DEF(pj_status_t) pj_sem_destroy(pj_sem_t *sem)
+{
+    PJ_ASSERT_RETURN(pool && sem, PJ_EINVAL);
+
+    return PJ_SUCCESS;
+}
+
+#endif	/* PJ_HAS_SEMAPHORE */
+
+
+
+