X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcutil%2Fsymbian%2Fsilcsymbianthread.cpp;h=05a2e893b294a22ed8b72e20ad838e0dc35dda49;hb=e7b6c157b80152bf9fb9266e6bdd93f9fb0db776;hp=c53e444385ef83bf4865f2f353feb9e19f4f9752;hpb=00607b678dedef3396c9d9ec48797ec50e4724a5;p=silc.git diff --git a/lib/silcutil/symbian/silcsymbianthread.cpp b/lib/silcutil/symbian/silcsymbianthread.cpp index c53e4443..05a2e893 100644 --- a/lib/silcutil/symbian/silcsymbianthread.cpp +++ b/lib/silcutil/symbian/silcsymbianthread.cpp @@ -18,12 +18,15 @@ */ #include "silc.h" +#include #include /**************************** SILC Thread API *******************************/ +extern "C" { + /* Thread structure for Symbian */ -typedef struct { +struct SilcSymbianThread { #ifdef SILC_THREADS SilcThreadStart start_func; void *context; @@ -31,25 +34,40 @@ typedef struct { #else void *tmp; #endif -} *SilcSymbianThread; +}; /* The actual thread function */ static TInt silc_thread_start(TAny *context) { #ifdef SILC_THREADS - SilcSymbianThread tc = (SilcSymbianThread)context; + SilcSymbianThread *tc = (SilcSymbianThread *)context; SilcThreadStart start_func = tc->start_func; - void *context = tc->context; + void *user_context = tc->context; SilcBool waitable = tc->waitable; + void *ret = NULL; + SilcTls tls; silc_free(tc); - /* Call the thread function */ - if (waitable) - silc_thread_exit(start_func(context)); - else - start_func(context); + tls = silc_thread_tls_init(); + + CTrapCleanup *cs = CTrapCleanup::New(); + if (cs) { + CActiveScheduler *s = new CActiveScheduler; + if(s) { + CActiveScheduler::Install(s); + + /* Call the thread function */ + TRAPD(ret_val, ret = start_func(user_context)); + + delete s; + } + delete cs; + } + + silc_free(tls); + silc_thread_exit(ret); #endif return KErrNone; @@ -58,17 +76,18 @@ static TInt silc_thread_start(TAny *context) /* Executed new thread */ SilcThread silc_thread_create(SilcThreadStart start_func, void *context, - bool waitable) + SilcBool waitable) { #ifdef SILC_THREADS - SilcSymbianThread tc; + SilcSymbianThread *tc; RThread *thread; TInt ret; - TBuf<32> name; + char tmp[24]; + SilcUInt16 wname[24]; SILC_LOG_DEBUG(("Creating new thread")); - tc = (SilcSymbianThread)silc_calloc(1, sizeof(*thread)); + tc = (SilcSymbianThread *)silc_calloc(1, sizeof(*tc)); if (!tc) return NULL; tc->start_func = start_func; @@ -76,18 +95,21 @@ SilcThread silc_thread_create(SilcThreadStart start_func, void *context, tc->waitable = waitable; /* Allocate thread */ - thread = new RThread(); + thread = new RThread; if (!thread) { silc_free(tc); return NULL; } /* Create the thread */ - name = (TText *)silc_time_string(0); - ret = thread->Create(name, silc_thread_start, 8192, 4096, 1024 * 1024, - (TAny *)tc); + silc_snprintf(tmp, sizeof(tmp), "thread-%p", tc); + silc_utf8_c2w((const unsigned char *)tmp, strlen(tmp), wname, + sizeof(wname) / sizeof(wname[0])); + TBuf<24> name((unsigned short *)wname); + name.PtrZ(); + ret = thread->Create(name, silc_thread_start, 8192, NULL, tc); if (ret != KErrNone) { - SILC_LOG_ERROR(("Could not create new thread")); + SILC_LOG_ERROR(("Could not create new thread, error %d", ret)); delete thread; silc_free(tc); return NULL; @@ -112,7 +134,7 @@ SilcThread silc_thread_create(SilcThreadStart start_func, void *context, void silc_thread_exit(void *exit_value) { #ifdef SILC_THREADS - RThread().Kill((Tint)exit_value); + RThread().Kill((TInt)exit_value); #endif } @@ -121,7 +143,8 @@ void silc_thread_exit(void *exit_value) SilcThread silc_thread_self(void) { #ifdef SILC_THREADS - return (SilcThread)&RThread(); + RThread thread = RThread(); + return (SilcThread)&thread; #else return NULL; #endif @@ -209,8 +232,8 @@ void silc_mutex_unlock(SilcMutex mutex) { #ifdef SILC_THREADS if (mutex) { - mutex->mutex->Signal(); mutex->locked = FALSE; + mutex->mutex->Signal(); } #endif /* SILC_THREADS */ } @@ -259,7 +282,7 @@ SilcBool silc_rwlock_alloc(SilcRwLock *rwlock) void silc_rwlock_free(SilcRwLock rwlock) { #ifdef SILC_THREADS - if (mutex) { + if (rwlock) { silc_mutex_free(rwlock->mutex); silc_cond_free(rwlock->cond); silc_free(rwlock); @@ -377,11 +400,41 @@ SilcBool silc_cond_timedwait(SilcCond cond, SilcMutex mutex, int timeout) { #ifdef SILC_THREADS - if (timeout) - return (cond->cond->TimedWait(*mutex->mutex, (TInt)timeout * 1000) == - KErrNone); + TInt ret; + if (timeout) { + ret = cond->cond->TimedWait(*mutex->mutex, (TInt)timeout * 1000); + if (ret != KErrNone) + SILC_LOG_DEBUG(("TimedWait returned %d", ret)); + return ret != KErrTimedOut; + } return (cond->cond->Wait(*mutex->mutex) == KErrNone); #else return FALSE; #endif /* SILC_THREADS*/ } + +/************************** Thread-local Storage ****************************/ + +SilcTls silc_thread_tls_init(void) +{ + SilcTls tls; + + if (silc_thread_get_tls()) + return silc_thread_get_tls(); + + /* Allocate Tls for the thread */ + tls = (SilcTls)silc_calloc(1, sizeof(*tls)); + if (!tls) + return NULL; + + Dll::SetTls(tls); + + return tls; +} + +SilcTls silc_thread_get_tls(void) +{ + return STATIC_CAST(SilcTls, Dll::Tls()); +} + +} /* extern "C" */