Index: pjproject/branches/symbian/pjlib/src/pj/os_core_symbian.cpp
===================================================================
--- pjproject/branches/symbian/pjlib/src/pj/os_core_symbian.cpp	(revision 788)
+++ pjproject/branches/symbian/pjlib/src/pj/os_core_symbian.cpp	(revision 789)
@@ -47,4 +47,12 @@
     void	   *tls_values[PJ_MAX_TLS];
 
+#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0
+    pj_uint32_t	    stk_size;
+    pj_uint32_t	    stk_max_usage;
+    char	   *stk_start;
+    const char	   *caller_file;
+    int		    caller_line;
+#endif
+
 } main_thread;
 
@@ -54,4 +62,9 @@
 };
 
+struct pj_sem_t
+{
+    int value;
+    int max;
+};
 
 /* Flags to indicate which TLS variables have been used */
@@ -67,5 +80,5 @@
 
 CPjTimeoutTimer::CPjTimeoutTimer()
-: CActive(EPriorityNormal), hasTimedOut_(false)
+: CActive(EPriorityNormal), hasTimedOut_(PJ_FALSE)
 {
 }
@@ -80,4 +93,5 @@
 void CPjTimeoutTimer::ConstructL()
 {
+    hasTimedOut_ = PJ_FALSE;
     timer_.CreateLocal();
     CActiveScheduler::Add(this);
@@ -86,5 +100,5 @@
 CPjTimeoutTimer *CPjTimeoutTimer::NewL()
 {
-    CPjTimeoutTimer *self = new (ELeave) CPjTimeoutTimer;
+    CPjTimeoutTimer *self = new CPjTimeoutTimer;
     CleanupStack::PushL(self);
 
@@ -101,17 +115,19 @@
 	Cancel();
 
-    hasTimedOut_ = false;
+    hasTimedOut_ = PJ_FALSE;
     timer_.After(iStatus, miliSeconds * 1000);
     SetActive();
+
+    pj_assert(iStatus==KRequestPending);
 }
 
 bool CPjTimeoutTimer::HasTimedOut() const
 {
-    return hasTimedOut_;
+    return hasTimedOut_ != 0;
 }
 
 void CPjTimeoutTimer::RunL()
 {
-    hasTimedOut_ = true;
+    hasTimedOut_ = PJ_TRUE;
 }
 
@@ -252,4 +268,7 @@
 {
     pj_ansi_strcpy(main_thread.obj_name, "pjthread");
+
+    // Init main thread
+    pj_memset(&main_thread, 0, sizeof(main_thread));
 
     // Initialize PjSymbianOS instance
@@ -365,5 +384,11 @@
 PJ_DEF(pj_status_t) pj_thread_sleep(unsigned msec)
 {
+    //Not a good idea, as we don't want network events to
+    //arrive while we're not polling them:
+    //PjSymbianOS::Instance()->WaitForActiveObjects();
+
+    //.. so rather use this, which won't wake up Active Objects:
     User::After(msec*1000);
+
     return PJ_SUCCESS;
 }
@@ -642,55 +667,118 @@
 				   unsigned initial, 
                                    unsigned max,
-				   pj_sem_t **sem)
-{
-    PJ_UNUSED_ARG(pool);
+				   pj_sem_t **p_sem)
+{
+    pj_sem_t *sem;
+ 
     PJ_UNUSED_ARG(name);
-    PJ_UNUSED_ARG(initial);
-    PJ_UNUSED_ARG(max);
+
+    sem = (pj_sem_t*) pj_pool_zalloc(pool, sizeof(pj_sem_t));
+    sem->value = initial;
+    sem->max = max;
+
+    *p_sem = sem;
+
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Wait for semaphore.
+ */
+PJ_DEF(pj_status_t) pj_sem_wait(pj_sem_t *sem)
+{
+    if (sem->value > 0) {
+	sem->value--;
+	return PJ_SUCCESS;
+    } else {
+	pj_assert(!"Unexpected!");
+	return PJ_EINVALIDOP;
+    }
+}
+
+
+/*
+ * Try wait for semaphore.
+ */
+PJ_DEF(pj_status_t) pj_sem_trywait(pj_sem_t *sem)
+{
+    if (sem->value > 0) {
+	sem->value--;
+	return PJ_SUCCESS;
+    } else {
+	pj_assert(!"Unexpected!");
+	return PJ_EINVALIDOP;
+    }
+}
+
+
+/*
+ * Release semaphore.
+ */
+PJ_DEF(pj_status_t) pj_sem_post(pj_sem_t *sem)
+{
+    sem->value++;
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Destroy semaphore.
+ */
+PJ_DEF(pj_status_t) pj_sem_destroy(pj_sem_t *sem)
+{
     PJ_UNUSED_ARG(sem);
-
-    /* Unsupported */
-    return PJ_ENOTSUP;
-}
-
-
-/*
- * Wait for semaphore.
- */
-PJ_DEF(pj_status_t) pj_sem_wait(pj_sem_t *sem)
-{
-    PJ_UNUSED_ARG(sem);
-    return PJ_EINVALIDOP;
-}
-
-
-/*
- * Try wait for semaphore.
- */
-PJ_DEF(pj_status_t) pj_sem_trywait(pj_sem_t *sem)
-{
-    PJ_UNUSED_ARG(sem);
-    return PJ_EINVALIDOP;
-}
-
-
-/*
- * Release semaphore.
- */
-PJ_DEF(pj_status_t) pj_sem_post(pj_sem_t *sem)
-{
-    PJ_UNUSED_ARG(sem);
-    return PJ_EINVALIDOP;
-}
-
-
-/*
- * Destroy semaphore.
- */
-PJ_DEF(pj_status_t) pj_sem_destroy(pj_sem_t *sem)
-{
-    PJ_UNUSED_ARG(sem);
-    return PJ_EINVALIDOP;
-}
-
-
+    return PJ_SUCCESS;
+}
+
+
+#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK != 0
+/*
+ * The implementation of stack checking. 
+ */
+PJ_DEF(void) pj_thread_check_stack(const char *file, int line)
+{
+    char stk_ptr;
+    pj_uint32_t usage;
+    pj_thread_t *thread = pj_thread_this();
+
+    pj_assert(thread);
+
+    /* Calculate current usage. */
+    usage = (&stk_ptr > thread->stk_start) ? &stk_ptr - thread->stk_start :
+		thread->stk_start - &stk_ptr;
+
+    /* Assert if stack usage is dangerously high. */
+    pj_assert("STACK OVERFLOW!! " && (usage <= thread->stk_size - 128));
+
+    /* Keep statistic. */
+    if (usage > thread->stk_max_usage) {
+	thread->stk_max_usage = usage;
+	thread->caller_file = file;
+	thread->caller_line = line;
+    }
+}
+
+/*
+ * Get maximum stack usage statistic. 
+ */
+PJ_DEF(pj_uint32_t) pj_thread_get_stack_max_usage(pj_thread_t *thread)
+{
+    return thread->stk_max_usage;
+}
+
+/*
+ * Dump thread stack status. 
+ */
+PJ_DEF(pj_status_t) pj_thread_get_stack_info(pj_thread_t *thread,
+					     const char **file,
+					     int *line)
+{
+    pj_assert(thread);
+
+    *file = thread->caller_file;
+    *line = thread->caller_line;
+    return 0;
+}
+
+#endif	/* PJ_OS_HAS_CHECK_STACK */
