odd crashes remain. However I was able to run mybot on SILCNet.
Basically tested scheduler, net routines, socket routines, threads
and some other utility routines.
After starting the Carbide.c++ you will need to import the SILC Toolkit
project. Go to File -> Import -> Symbian OS -> Symbian OS Bld.inf file,
-and go to the extracted SILC Toolkit source tree and find symbian/bld.inf
+and go to the extracted SILC Toolkit source tree and find symbian\bld.inf
file and import it. When Carbide.c++ asks for the Root Directory, select
the root of the extracted SILC Toolkit source tree, if not already
selected.
continue;
} else {
- /* Error */
- if (silc_likely(errno == EINTR))
+ /* Error or special case handling */
+ if (errno == EINTR)
continue;
+ if (ret == -2)
+ break;
+
SILC_LOG_ERROR(("Error in select()/poll(): %s", strerror(errno)));
continue;
}
/* Runs the scheduler and blocks here. When this returns the scheduler
has ended. */
+#ifndef SILC_SYMBIAN
void silc_schedule(SilcSchedule schedule)
{
SILC_LOG_DEBUG(("Running scheduler"));
silc_schedule_iterate(schedule, -1);
SILC_SCHEDULE_UNLOCK(schedule);
}
+#endif /* !SILC_SYMBIAN */
/* Wakes up the scheduler. This is used only in multi-threaded
environments where threads may add new tasks or remove old tasks
out:
SILC_SCHEDULE_UNLOCK(schedule);
+
+#ifdef SILC_SYMBIAN
+ /* On symbian we wakeup scheduler immediately after adding timeout task
+ in case the task is added outside the scheduler loop (in some active
+ object). */
+ if (task && task->type == 1)
+ silc_schedule_wakeup(schedule);
+#endif /* SILC_SYMBIAN */
+
return task;
}
*
* DESCRIPTION
*
- * The SILC scheduler. The program will run inside this function.
- * When this returns the program is to be ended. Before this function can
- * be called, one must call silc_schedule_init function.
+ * The SILC scheduler. The program will run inside this function.
+ * When this returns the program is to be ended. Before this function
+ * can be called, one must call silc_schedule_init function.
*
* NOTES
*
- * On Windows this will block the program, but will continue dispatching
- * window messages, and thus can be used as the main loop of the program.
+ * On Windows this will block the calling thread but will continue
+ * to dispatch window messages, and thus can be used as the main loop
+ * of the program.
*
- * On Symbian this will return immediately. On Symbian calling
- * silc_schedule is same as calling silc_schedule_one. This also means
- * the caller must be already running Symbian Active Scheduler.
+ * On Symbian this will block the calling thread. The Symbian Active
+ * Scheduler must be running before calling this function.
*
***/
void silc_schedule(SilcSchedule schedule);
stream->ops = &silc_socket_stream_ops;
stream->sock = sock;
stream->schedule = schedule;
+ stream->connected = TRUE;
l = silc_calloc(1, sizeof(*l));
if (!l) {
* If the `waitable' is TRUE then another thread must always issue
* silc_thread_wait to avoid memory leaks.
*
+ * On Symbian Cleanup Stack is created and new Active Scheduler is
+ * installed automatically for the created thread. The thread also
+ * shares heap with the calling thread.
+ *
***/
SilcThread silc_thread_create(SilcThreadStart start_func, void *context,
SilcBool waitable);
#include "silc.h"
#include "silcsymbiansocketstream.h"
+/************************ Static utility functions **************************/
+
+static SilcBool silc_net_set_sockaddr(TInetAddr *addr, const char *ip_addr,
+ int port)
+{
+ /* Check for IPv4 and IPv6 addresses */
+ if (ip_addr) {
+ if (!silc_net_is_ip(ip_addr)) {
+ SILC_LOG_ERROR(("%s is not IP address", ip_addr));
+ return FALSE;
+ }
+
+ if (silc_net_is_ip4(ip_addr)) {
+ /* IPv4 address */
+ unsigned char buf[4];
+ TUint32 a;
+
+ if (!silc_net_addr2bin(ip_addr, buf, sizeof(buf)))
+ return FALSE;
+
+ SILC_GET32_MSB(a, buf);
+ addr->SetAddress(a);
+ addr->SetPort(port);
+ } else {
+#ifdef HAVE_IPV6
+ SILC_LOG_ERROR(("IPv6 not supported"));
+ return FALSE;
+#else
+ SILC_LOG_ERROR(("Operating System does not support IPv6"));
+ return FALSE;
+#endif
+ }
+ } else {
+ addr->SetAddress(0);
+ addr->SetPort(port);
+ }
+
+ return TRUE;
+}
+
/****************************** TCP Listener ********************************/
class SilcSymbianTCPListener;
SilcSymbianTCPListener *l = NULL;
TInetAddr server;
TInt ret;
- TBuf<64> tmp;
int i;
SILC_LOG_DEBUG(("Creating TCP listener"));
if (ret != KErrNone)
goto err;
+#ifdef SILC_THREADS
+ /* Make our socket shareable between threads */
+ l->ss.ShareAuto();
+#endif /* SILC_THREADS */
+
/* Set listener address */
- if (local_ip_addr) {
- server = TInetAddr(port);
- tmp = (TText *)local_ip_addr[i];
- ret = server.Input(tmp);
- if (ret != KErrNone)
- goto err;
- } else {
- server = TInetAddr(KInetAddrAny, port);
- }
+ if (!silc_net_set_sockaddr(&server, local_ip_addr[i], port))
+ goto err;
/* Create the socket */
ret = l->sock.Open(l->ss, KAfInet, KSockStream, KProtocolInetTcp);
(SilcSocket)silc_create_symbian_socket(sock, ss),
TRUE, FALSE, schedule, silc_net_connect_stream,
(void *)this);
+ sock = NULL;
+ ss = NULL;
} else {
sock->Close();
delete sock;
SilcSymbianTCPConnect *conn;
TInetAddr local, remote;
SilcNetStatus status;
- TBuf<64> tmp;
TInt ret;
if (!remote_ip_addr || remote_port < 1 || !schedule || !callback)
/* Connect to socket server */
ret = conn->ss->Connect();
if (ret != KErrNone) {
+ SILC_LOG_ERROR(("Error connecting to socket server, error %d", ret));
status = SILC_NET_ERROR;
goto err;
}
+#ifdef SILC_THREADS
+ /* Make our socket shareable between threads */
+ conn->ss->ShareAuto();
+#endif /* SILC_THREADS */
+
/* Start async operation */
conn->op = silc_async_alloc(silc_net_connect_abort, NULL, (void *)conn);
if (!conn->op) {
conn->sock->SetOpt(KSoTcpKeepAlive, KSolInetTcp, 1);
/* Bind to the local address if provided */
- if (local_ip_addr) {
- local = TInetAddr(0);
- tmp = (TText *)local_ip_addr;
- ret = local.Input(tmp);
- if (ret == KErrNone)
- ret = conn->sock->Bind(local);
- }
+ if (local_ip_addr)
+ if (silc_net_set_sockaddr(&local, local_ip_addr, 0))
+ conn->sock->Bind(local);
/* Connect to the host */
- remote = TInetAddr(remote_port);
- tmp = (TText *)conn->remote_ip;
- ret = remote.Input(tmp);
- if (ret != KErrNone) {
- SILC_LOG_ERROR(("Cannot connect (cannot set address), error %d", ret));
+ if (!silc_net_set_sockaddr(&remote, conn->remote_ip, remote_port)) {
+ SILC_LOG_ERROR(("Cannot connect (cannot set address)"));
status = SILC_NET_ERROR;
goto err;
}
TRequestStatus status;
RSocket *sock = NULL;
RSocketServ *ss = NULL;
- TBuf<64> tmp;
TInt ret;
SILC_LOG_DEBUG(("Creating UDP stream"));
if (ret != KErrNone)
goto err;
+#ifdef SILC_THREADS
+ /* Make our socket shareable between threads */
+ ss->ShareAuto();
+#endif /* SILC_THREADS */
+
/* Get local bind address */
- if (local_ip_addr) {
- local = TInetAddr(local_port);
- tmp = (TText *)local_ip_addr;
- ret = local.Input(tmp);
- if (ret != KErrNone)
- goto err;
- } else {
- local = TInetAddr(KInetAddrAny, local_port);
- }
+ if (!silc_net_set_sockaddr(&local, local_ip_addr, local_port))
+ goto err;
/* Create the socket */
ret = sock->Open(*ss, KAfInet, KSockDatagram, KProtocolInetUdp);
/* Set to connected state if remote address is provided. */
if (remote_ip_addr && remote_port) {
- remote = TInetAddr(remote_port);
- tmp = (TText *)remote_ip_addr;
- ret = remote.Input(tmp);
- if (ret != KErrNone)
- goto err;
-
- sock->Connect(remote, status);
- if (status != KErrNone) {
- SILC_LOG_DEBUG(("Cannot connect UDP stream"));
- goto err;
+ if (silc_net_set_sockaddr(&remote, remote_ip_addr, remote_port)) {
+ sock->Connect(remote, status);
+ if (status != KErrNone) {
+ SILC_LOG_DEBUG(("Cannot connect UDP stream"));
+ goto err;
+ }
}
}
return (SilcUInt16)addr.Port();
}
-} /* extern "C" */
\ No newline at end of file
+} /* extern "C" */
-/*\r
-\r
- silcsymbianschduler.cpp\r
-\r
- Author: Pekka Riikonen <priikone@silcnet.org>\r
-\r
- Copyright (C) 1998 - 2007 Pekka Riikonen\r
-\r
- This program is free software; you can redistribute it and/or modify\r
- it under the terms of the GNU General Public License as published by\r
- the Free Software Foundation; version 2 of the License.\r
-\r
- This program is distributed in the hope that it will be useful,\r
- but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- GNU General Public License for more details.\r
-\r
-*/\r
-\r
-/* On symbian the SILC Scheduler doesn't do anything. All timeout tasks\r
- are dispatched by the generic scheduler implementation. Sockets and\r
- file descriptors are dispatched automatically in their class\r
- implementation, so adding FD Tasks on Symbian doesn't do anything.\r
-\r
- This also means that on Symbian the SILC Scheduler always returns\r
- immediately. Because FD tasks use the Symbian scheduler the performance\r
- is as good as it can be. For timeout tasks the performance is not an\r
- issue. */\r
-\r
-#include "silc.h"\r
-\r
-extern "C" {\r
-\r
-int silc_poll(SilcSchedule schedule, void *context)\r
-{\r
- /* Return immediately, timeout. */\r
- return 0;\r
-}\r
-\r
-SilcBool silc_schedule_internal_schedule_fd(SilcSchedule schedule,\r
- void *context,\r
- SilcTaskFd task,\r
- SilcTaskEvent event_mask)\r
-{\r
- /* Nothing to do */\r
- return TRUE;\r
-}\r
-\r
-void *silc_schedule_internal_init(SilcSchedule schedule,\r
- void *app_context)\r
-{\r
- /* Nothing to do */\r
- return (void *)1;\r
-}\r
-\r
-\r
-void silc_schedule_internal_uninit(SilcSchedule schedule, void *context)\r
-{\r
- /* Nothing to do */\r
-}\r
-\r
-void silc_schedule_internal_wakeup(SilcSchedule schedule, void *context)\r
-{\r
- /* Nothing to do */\r
-}\r
-\r
-void silc_schedule_internal_signal_register(SilcSchedule schedule,\r
- void *context,\r
- SilcUInt32 sig,\r
- SilcTaskCallback callback,\r
- void *callback_context)\r
-{\r
- /* Nothing to do */\r
-}\r
-\r
-void silc_schedule_internal_signal_unregister(SilcSchedule schedule,\r
- void *context,\r
- SilcUInt32 sig)\r
-{\r
- /* Nothing to do */\r
-}\r
-\r
-void silc_schedule_internal_signals_call(SilcSchedule schedule, void *context)\r
-{\r
- /* Nothing to do */\r
-}\r
-\r
-void silc_schedule_internal_signals_block(SilcSchedule schedule, void *context)\r
-{\r
- /* Nothing to do */\r
-}\r
-\r
-void silc_schedule_internal_signals_unblock(SilcSchedule schedule,\r
- void *context)\r
-{\r
- /* Nothing to do */\r
-}\r
-\r
-EXPORT_C const SilcScheduleOps schedule_ops =\r
-{\r
- silc_schedule_internal_init,\r
- silc_schedule_internal_uninit,\r
- silc_poll,\r
- silc_schedule_internal_schedule_fd,\r
- silc_schedule_internal_wakeup,\r
- silc_schedule_internal_signal_register,\r
- silc_schedule_internal_signal_unregister,\r
- silc_schedule_internal_signals_call,\r
- silc_schedule_internal_signals_block,\r
- silc_schedule_internal_signals_unblock,\r
-};\r
-\r
-} /* extern "C" */
\ No newline at end of file
+/*
+
+ silcsymbianscheduler.cpp
+
+ Author: Pekka Riikonen <priikone@silcnet.org>
+
+ Copyright (C) 2007 Pekka Riikonen
+
+ 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; version 2 of the License.
+
+ 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.
+
+*/
+
+#include "silc.h"
+#include <e32base.h>
+
+/* The SILC Scheduler for Symbian handles only timeout tasks. Fd tasks are
+ not handled by the SILC Scheduler at all but are handled by the Symbian's
+ Active Scheduler. Fd and socket stream callbacks are delivered back
+ to caller in their respective class implementatios.
+
+ The SILC Scheduler in Symbian works by creating CActiveSchedulerWait
+ when silc_schedule() is called. This will block the calling thread just
+ like silc_schedule is supposed to do. Under that Active Scheduler we
+ run our SilcSymbianScheduler timer which will handle the actual SILC
+ Scheduler by calling silc_schedule_one at correct times. The timeout
+ values are selected by the SILC Scheduler itself when silc_schedule_one
+ is called. After that call returns we go back to the Active Scheduler
+ to dispatch other active objects and to wait for next timeout.
+
+ Wakeup of the scheduler works by simply cancelling the outstanding timeout
+ and issuing a zero timeout to call the silc_schedule_one again.
+
+ If user directly calls silc_schedule_one it behaves same as on other
+ platforms. */
+
+class SilcSymbianScheduler;
+class SilcSymbianSchedulerWakeup;
+
+typedef struct {
+ SilcSymbianScheduler *timer;
+ SilcSymbianSchedulerWakeup *wakeup;
+} *SilcSymbianInternal;
+
+/* SILC scheduler timer class. This handles the actual SILC Scheduler
+ by calling silc_schedule_one and scheduling the scheduler timeouts. */
+class SilcSymbianScheduler : public CTimer {
+public:
+ /* Constructor */
+ SilcSymbianScheduler() : CTimer(CActive::EPriorityStandard)
+ {
+ CTimer::ConstructL();
+ CActiveScheduler::Add(this);
+ After(0);
+ }
+
+ /* Destructor */
+ ~SilcSymbianScheduler()
+ {
+ Cancel();
+ }
+
+ /* Timeout callback */
+ virtual void RunL()
+ {
+ if (!silc_schedule_one(schedule, -1))
+ s->AsyncStop();
+ }
+
+ CActiveSchedulerWait *s;
+ SilcSchedule schedule;
+};
+
+/* Scheduler wakeup class */
+class SilcSymbianSchedulerWakeup : public CActive {
+public:
+ /* Constructor */
+ SilcSymbianSchedulerWakeup() : CActive(CActive::EPriorityStandard)
+ {
+ CActiveScheduler::Add(this);
+ iStatus = KRequestPending;
+ SetActive();
+ }
+
+ /* Destructor */
+ ~SilcSymbianSchedulerWakeup()
+ {
+ Cancel();
+ }
+
+ /* Wakeup */
+ void Wakeup(TThreadId thread_id)
+ {
+ if (wake_signal)
+ return;
+ wake_signal = TRUE;
+
+ TRequestStatus *status = &iStatus;
+ if (id != thread_id)
+ thread.RequestComplete(status, KErrNone);
+ else
+ User::RequestComplete(status, KErrNone);
+ }
+
+ /* Timeout callback */
+ virtual void RunL()
+ {
+ SILC_LOG_DEBUG(("Wakeup scheduler"));
+
+ /* Wakeup scheduler */
+ timer->Cancel();
+ timer->After(0);
+ wake_signal = FALSE;
+
+ iStatus = KRequestPending;
+ SetActive();
+ }
+
+ virtual void DoCancel()
+ {
+
+ }
+
+ RThread thread;
+ TThreadId id;
+ SilcSymbianScheduler *timer;
+ unsigned int wake_signal : 1;
+};
+
+extern "C" {
+
+/* Symbian's silc_schedule call. We start Active Scheduler here and start
+ our SILC Scheduler. The calling thread will block here. */
+
+void silc_schedule(SilcSchedule schedule)
+{
+ SilcSymbianInternal internal = (SilcSymbianInternal)schedule->internal;
+ CActiveSchedulerWait *s;
+
+ SILC_LOG_DEBUG(("Running scheduler"));
+
+ /* Create Active Scheduler */
+ s = new CActiveSchedulerWait;
+ SILC_ASSERT(s);
+
+ /* Start SILC Scheduler */
+ internal->timer = new SilcSymbianScheduler;
+ SILC_ASSERT(internal->timer);
+ internal->timer->schedule = schedule;
+ internal->timer->s = s;
+ internal->wakeup = new SilcSymbianSchedulerWakeup;
+ SILC_ASSERT(internal->wakeup);
+ internal->wakeup->id = RThread().Id();
+ internal->wakeup->thread.Open(internal->wakeup->id);
+ internal->wakeup->timer = internal->timer;
+
+ /* Start Active Scheduler */
+ s->Start();
+
+ delete internal->wakeup;
+ delete internal->timer;
+ delete s;
+}
+
+int silc_poll(SilcSchedule schedule, void *context)
+{
+ SilcSymbianInternal internal = (SilcSymbianInternal)context;
+ int timeout = -1;
+ TTime at_timeout;
+
+ /* When user is using silc_schedule_one we don't have our timer set,
+ so just return immediately. */
+ if (!internal->timer)
+ return 0;
+
+ /* Schedule next timeout */
+ if (schedule->has_timeout)
+ timeout = ((schedule->timeout.tv_sec * 1000) +
+ (schedule->timeout.tv_usec / 1000));
+
+ if (!timeout)
+ return 0;
+
+ if (timeout == -1)
+ timeout = 0;
+
+ /* Set the timeout value */
+ at_timeout.HomeTime();
+ while (timeout > 2100 * 1000) {
+ at_timeout += (TTimeIntervalMicroSeconds32)(2100 * 1000 * 1000);
+ timeout -= (2100 * 1000);
+ }
+ at_timeout += (TTimeIntervalMicroSeconds32)timeout;
+
+ /* Schedule the timeout */
+ internal->timer->At(at_timeout);
+
+ /* Return special "ignore" value. Causes the scheduler to just break
+ the scheduler iteration and return back to its caller. */
+ return -2;
+}
+
+SilcBool silc_schedule_internal_schedule_fd(SilcSchedule schedule,
+ void *context,
+ SilcTaskFd task,
+ SilcTaskEvent event_mask)
+{
+ /* Nothing to do */
+ return TRUE;
+}
+
+void *silc_schedule_internal_init(SilcSchedule schedule,
+ void *app_context)
+{
+ SilcSymbianInternal internal;
+
+ internal = (SilcSymbianInternal)silc_calloc(1, sizeof(*internal));
+ if (!internal)
+ return NULL;
+
+ return internal;
+}
+
+void silc_schedule_internal_uninit(SilcSchedule schedule, void *context)
+{
+ SilcSymbianInternal internal = (SilcSymbianInternal)context;
+ silc_free(internal);
+}
+
+void silc_schedule_internal_wakeup(SilcSchedule schedule, void *context)
+{
+#ifdef SILC_THREADS
+ SilcSymbianInternal internal = (SilcSymbianInternal)context;
+ TThreadId id;
+
+ if (!internal->timer)
+ return;
+
+ id = RThread().Id();
+ internal->wakeup->Wakeup(id);
+#endif /* SILC_THREADS */
+}
+
+void silc_schedule_internal_signal_register(SilcSchedule schedule,
+ void *context,
+ SilcUInt32 sig,
+ SilcTaskCallback callback,
+ void *callback_context)
+{
+ /* Nothing to do */
+}
+
+void silc_schedule_internal_signal_unregister(SilcSchedule schedule,
+ void *context,
+ SilcUInt32 sig)
+{
+ /* Nothing to do */
+}
+
+void silc_schedule_internal_signals_call(SilcSchedule schedule, void *context)
+{
+ /* Nothing to do */
+}
+
+void silc_schedule_internal_signals_block(SilcSchedule schedule, void *context)
+{
+ /* Nothing to do */
+}
+
+void silc_schedule_internal_signals_unblock(SilcSchedule schedule,
+ void *context)
+{
+ /* Nothing to do */
+}
+
+EXPORT_C const SilcScheduleOps schedule_ops =
+{
+ silc_schedule_internal_init,
+ silc_schedule_internal_uninit,
+ silc_poll,
+ silc_schedule_internal_schedule_fd,
+ silc_schedule_internal_wakeup,
+ silc_schedule_internal_signal_register,
+ silc_schedule_internal_signal_unregister,
+ silc_schedule_internal_signals_call,
+ silc_schedule_internal_signals_block,
+ silc_schedule_internal_signals_unblock,
+};
+
+} /* extern "C" */
{
SILC_LOG_DEBUG(("Send()"));
s->sock->Send(buf, 0, iStatus, ret_len);
- SetActive();
+ if (!IsActive())
+ SetActive();
}
/* Send data */
tmp = (TText *)remote_ip;
if (remote.Input(tmp) == KErrNone) {
s->sock->SendTo(buf, remote, 0, iStatus, ret_len);
- SetActive();
+ if (!IsActive())
+ SetActive();
}
}
{
SILC_LOG_DEBUG(("Read()"));
- if (!s->stream || s->stream->connected)
+ if (s->stream && s->stream->connected)
s->sock->RecvOneOrMore(inbuf, 0, iStatus, read_len);
else
s->sock->RecvFrom(inbuf, remote, 0, iStatus);
silc_free(stream);
return NULL;
}
+ stream->send->s = stream;
stream->receive = new SilcSymbianSocketReceive;
if (!stream->receive) {
silc_free(stream);
return NULL;
}
+ stream->receive->s = stream;
stream->receive->inbuf_ptr = NULL;
stream->receive->inbuf_len = 0;
*/
#include "silc.h"
+#include <e32base.h>
#include <e32std.h>
/**************************** SILC Thread API *******************************/
extern "C" {
/* Thread structure for Symbian */
-typedef struct {
+struct SilcSymbianThread {
#ifdef SILC_THREADS
SilcThreadStart start_func;
void *context;
#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 *user_context = tc->context;
SilcBool waitable = tc->waitable;
+ void *ret = NULL;
silc_free(tc);
- /* Call the thread function */
- if (waitable)
- silc_thread_exit(start_func(user_context));
- else
- start_func(user_context);
+ 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_thread_exit(ret);
#endif
return KErrNone;
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;
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;
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*/
}
-} /* extern "C" */
\ No newline at end of file
+} /* extern "C" */
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 2006 Pekka Riikonen
+ Copyright (C) 2006 - 2007 Pekka Riikonen
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
char *silc_get_username()
{
+#if 0
char *logname = NULL;
logname = getlogin();
}
return strdup(logname);
+#else
+ return strdup("Symbian");
+#endif /* 0 */
}
/* Returns the real name of ther user. */
char *silc_get_real_name()
{
+#if 0
char *realname = NULL;
struct passwd *pw;
realname = strdup(pw->pw_gecos);
return realname;
+#else
+ return strdup("Lastname");
+#endif /* 0 */
}
/* Return current time to struct timeval. */
void silc_symbian_debug(const char *function, int line, char *string)
{
- RDebug::Print(_L("%s:%d: %s"), function, line, string);
+ fprintf(stderr, "%s:%d: %s\n", function, line, string);
+ // RDebug::Print(_L("%s:%d: %s"), function, line, string);
}
} /* extern "C" */
/* HAVE_VA_COPY */
//#define HAVE_VA_COPY
-#define HAVE_VA_COPY_AARRAY
+#define HAVE_VA_COPY_ARRAY
/* Name of package */
#define PACKAGE "silc-toolkit"