silc_schedule_get_global if provided scheduler argument is NULL.
+Wed Dec 26 13:10:30 EET 2007 Pekka Riikonen <priikone@silcnet.org>
+
+ * Added silc_schedule_[set|get]_global to
+ lib/silcutil/silcschedule.[ch].
+
+ * Changed many APIs to call silc_schedule_get_global if provided
+ scheduler argument is NULL.
+
Tue Dec 25 18:44:27 EET 2007 Pekka Riikonen <priikone@silcnet.org>
* silc_stack_alloc now automatically aligns the requested
o silc_getopt routines (***DONE)
+ o regex from /lib/contrib to lib/silcutil.
+
o The SILC Event signals. Asynchronous events that can be created,
connected to and signalled. Either own event routines or glued into
SilcSchedule:
const char *option; /* Option name */
const char *display_name; /* Option displayable name */
SilcParamType type; /* Option data format */
+ void *default_value; /* Option's default value */
+ SilcUInt32 default_value_len; /* Default value length */
} *SilcAcceleratorOption;
For software accelerator it could be for example:
- { "min_threads", "Minimum threads", SILC_PARAM_UINT32 },
- { "max_threads", "Maximum threads", SILC_PARAM_UINT32 },
-
- The accelerator itself doesn't have to use the option structure to
- parse the options if not wanted. It is defined for the caller so
- they can learn the supported options in a well defined way.
+ { "min_threads", "Minimum threads", SILC_PARAM_UINT32, (void *)2, 4 },
+ { "max_threads", "Maximum threads", SILC_PARAM_UINT32, (void *)4, 4 },
o Diffie-Hellman acceleration
SILC_LOG_DEBUG(("Start HTTP server at %s:%d", ip, port));
+ if (!schedule)
+ schedule = silc_schedule_get_global();
+
if (!ip || !schedule || !callback)
return FALSE;
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
* `port'. The `callback' with `context' will be called everytime a new
* HTTP request comes to the server from a HTTP client. In that callback
* the caller must then reply with the requested Web page or with error.
+ * If the `schedule' is NULL this will call silc_schedule_get_global to
+ * try to get global scheduler.
*
***/
SilcHttpServer silc_http_server_alloc(const char *ip, SilcUInt16 port,
SILC_LOG_DEBUG(("Starting SFTP client"));
+ if (!schedule)
+ schedule = silc_schedule_get_global();
+
if (!stream)
return NULL;
{
SilcSFTPServer server;
+ if (!schedule)
+ schedule = silc_schedule_get_global();
+
server = silc_calloc(1, sizeof(*server));
if (!server)
return NULL;
* used to read and write the SFTP packets. The `error_cb' will be called
* in case a stream error occurs, such as end of stream.
*
+ * If `schedule' is NULL this will call silc_schedule_get_global to try to
+ * get global scheduler.
+ *
***/
SilcSFTP silc_sftp_client_start(SilcStream stream,
SilcSchedule schedule,
* responsible of closing and destroying the `stream'. The `fs' is the
* filesystem context allocated by the application.
*
+ * If `schedule' is NULL this will call silc_schedule_get_global to try to
+ * get global scheduler.
+ *
***/
SilcSFTP silc_sftp_server_start(SilcStream stream,
SilcSchedule schedule,
SilcSchedule schedule)
{
if (!schedule) {
- silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
- return FALSE;
+ schedule = silc_schedule_get_global();
+ if (!schedule) {
+ silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
+ return FALSE;
+ }
}
fsm->fsm_context = fsm_context;
* caller must free the returned context with silc_fsm_free. The
* `fsm_context' is delivered to every FSM state function. The `schedule'
* is the caller's scheduler and the FSM will be run in the scheduler.
- * Returns NULL if system is out of memory.
+ * If `schedule' is NULL this will call silc_schedule_get_global to try
+ * get global scheduler. Returns NULL on error or if system is out of
+ * memory.
*
* EXAMPLE
*
* as argument. The silc_fsm_free must not be called if this was called.
* Returns TRUE if the initialization is Ok or FALSE if error occurred.
* This function does not allocate any memory. The `schedule' is the
- * caller's scheduler and the FSM will be run in the scheduler.
+ * caller's scheduler and the FSM will be run in the scheduler. If
+ * `schedule' is NULL this will call silc_schedule_get_global to try to
+ * get global scheduler.
*
* EXAMPLE
*
* thread context with silc_fsm_free. If the 'real_thread' is TRUE
* then the thread will actually be executed in real thread, if platform
* supports them. The `thread_context' is delivered to every state
- * function in the thread. Returns NULL if the system is out of memory.
+ * function in the thread. Returns NULL on error or if the system is out
+ * of memory.
*
* NOTES
*
FILE *fp = NULL;
SilcLog log;
+ if (!scheduler)
+ scheduler = silc_schedule_get_global();
+
log = silc_log_get_context(type);
if (!log)
return FALSE;
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1997 - 2006 Pekka Riikonen
+ Copyright (C) 1997 - 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
* SYNOPSIS
*
* SilcBool silc_log_set_file(SilcLogType type, char *filename,
- * SilcUInt32 maxsize,
- * SilcSchedule scheduler);
+ * SilcUInt32 maxsize,
+ * SilcSchedule scheduler);
*
* DESCRIPTION
*
* You can disable logging for a channel by specifying NULL filename, the
* maxsize in this case is not important. The `scheduler' parameter is
* needed by the internal logging to allow buffered output and thus to
- * save HD activity.
+ * save HD activity. If `scheduler' is NULL this will call
+ * silc_schedule_get_global to try to get global scheduler.
*
***/
SilcBool silc_log_set_file(SilcLogType type, char *filename,
{
SilcNetResolveContext r = silc_calloc(1, sizeof(*r));
+ if (!schedule) {
+ schedule = silc_schedule_get_global();
+ SILC_VERIFY(schedule);
+ }
+
r->completion = completion;
r->context = context;
r->prefer_ipv6 = prefer_ipv6;
{
SilcNetResolveContext r = silc_calloc(1, sizeof(*r));
+ if (!schedule) {
+ schedule = silc_schedule_get_global();
+ SILC_VERIFY(schedule);
+ }
+
r->completion = completion;
r->context = context;
r->schedule = schedule;
* is zero (0), operating system will define it automatically.
*
* The `callback' always delivers valid new stream. It is not called
- * with an error status.
+ * with an error status. If `schedule' is NULL this will call
+ * silc_schedule_get_global to try to get global scheduler.
*
***/
SilcNetListener
* then the incoming connection hostname will be resolved.
*
* The `callback' always delivers valid new stream. It is not called
- * with an error status.
+ * with an error status. If `schedule' is NULL this will call
+ * silc_schedule_get_global to try to get global scheduler.
*
***/
SilcNetListener
* The returned SilcAsyncOperation context can be used to control the
* asynchronous connecting, such as to abort it. If it is aborted
* using silc_async_abort the `callback' will not be called. If NULL
- * is returned the operation cannot be aborted.
+ * is returned the operation cannot be aborted. If `schedule' is NULL
+ * this will call silc_schedule_get_global to try to get global scheduler.
*
***/
SilcAsyncOperation silc_net_tcp_connect(const char *local_ip_addr,
* To read the packet use silc_stream_read if the remote address was
* provided, and silc_net_udp_receive if it was not.
*
- * Supports IPv6 if the platform supports it.
+ * Supports IPv6 if the platform supports it. If `schedule' is NULL this
+ * will call silc_schedule_get_global to try to get global scheduler.
*
* EXAMPLE
*
* Asynchronously resolves the IP address of the hostname indicated
* by the `name'. This function returns immediately, and the
* `completion' callback will be called after the resolving is
- * completed.
+ * completed. If `schedule' is NULL this will call silc_schedule_get_global
+ * to try to get global scheduler.
*
* If the `prefer_ipv6' is TRUE then this will return IPv6 address if it
* finds. If FALSE if returns IPv4 address even if it found IPv6
* Asynchronously resolves the hostname for the IP address indicated
* by the `addr'. This function returns immediately, and the
* `completion' callback will be called after the resolving is
- * completed.
+ * completed. If `schedule' is NULL this will call silc_schedule_get_global
+ * to try to get global scheduler.
*
***/
void silc_net_gethostbyaddr_async(const char *addr,
{
SilcTaskFd ftask;
fprintf(stdout, "Schedule %p statistics:\n\n", schedule);
- fprintf(stdout, "Num FD tasks : %lu (%lu bytes allocated)\n",
+ fprintf(stdout, "Num FD tasks : %d (%lu bytes allocated)\n",
silc_hash_table_count(schedule->fd_queue),
sizeof(*ftask) * silc_hash_table_count(schedule->fd_queue));
- fprintf(stdout, "Num Timeout tasks : %d (%d bytes allocated)\n",
+ fprintf(stdout, "Num Timeout tasks : %d (%lu bytes allocated)\n",
silc_list_count(schedule->timeout_queue),
sizeof(struct SilcTaskTimeoutStruct) *
silc_list_count(schedule->timeout_queue));
- fprintf(stdout, "Num Timeout freelist : %d (%d bytes allocated)\n",
+ fprintf(stdout, "Num Timeout freelist : %d (%lu bytes allocated)\n",
silc_list_count(schedule->free_tasks),
sizeof(struct SilcTaskTimeoutStruct) *
silc_list_count(schedule->free_tasks));
{
SilcTask task;
+ SILC_VERIFY(schedule);
+
SILC_LOG_DEBUG(("Uninitializing scheduler %p", schedule));
if (schedule->valid == TRUE)
void silc_schedule_stop(SilcSchedule schedule)
{
SILC_LOG_DEBUG(("Stopping scheduler"));
+ SILC_VERIFY(schedule);
SILC_SCHEDULE_LOCK(schedule);
schedule->valid = FALSE;
SILC_SCHEDULE_UNLOCK(schedule);
schedule->notify_context = context;
}
+/* Set global scheduler */
+
+void silc_schedule_set_global(SilcSchedule schedule)
+{
+ SilcTls tls = silc_thread_get_tls();
+
+ if (!tls) {
+ /* Try to initialize Tls */
+ tls = silc_thread_tls_init();
+ SILC_VERIFY(tls);
+ if (!tls)
+ return;
+ }
+
+ SILC_LOG_DEBUG(("Setting global scheduler %p", schedule));
+
+ tls->schedule = schedule;
+}
+
+/* Return global scheduler */
+
+SilcSchedule silc_schedule_get_global(void)
+{
+ SilcTls tls = silc_thread_get_tls();
+
+ if (!tls)
+ return NULL;
+
+ SILC_LOG_DEBUG(("Return global scheduler %p", tls->schedule));
+
+ return tls->schedule;
+}
+
/* Add new task to the scheduler */
SilcTask silc_schedule_task_add(SilcSchedule schedule, SilcUInt32 fd,
{
SilcTask task = NULL;
+ if (!schedule) {
+ schedule = silc_schedule_get_global();
+ SILC_VERIFY(schedule);
+ if (!schedule) {
+ silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
+ return NULL;
+ }
+ }
+
if (silc_unlikely(!schedule->valid)) {
silc_set_errno(SILC_ERR_NOT_VALID);
return NULL;
SilcBool silc_schedule_task_del(SilcSchedule schedule, SilcTask task)
{
+ if (!schedule) {
+ schedule = silc_schedule_get_global();
+ SILC_VERIFY(schedule);
+ if (!schedule) {
+ silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
+ return FALSE;
+ }
+ }
+
if (silc_unlikely(task == SILC_ALL_TASKS)) {
SilcHashTableList htl;
SILC_LOG_DEBUG(("Unregister task by fd %d", fd));
+ if (!schedule) {
+ schedule = silc_schedule_get_global();
+ SILC_VERIFY(schedule);
+ if (!schedule) {
+ silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
+ return FALSE;
+ }
+ }
+
SILC_SCHEDULE_LOCK(schedule);
/* fd is unique, so there is only one task with this fd in the table */
SILC_LOG_DEBUG(("Unregister task by callback"));
+ if (!schedule) {
+ schedule = silc_schedule_get_global();
+ SILC_VERIFY(schedule);
+ if (!schedule) {
+ silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
+ return FALSE;
+ }
+ }
+
SILC_SCHEDULE_LOCK(schedule);
/* Delete from fd queue */
SILC_LOG_DEBUG(("Unregister task by context"));
+ if (!schedule) {
+ schedule = silc_schedule_get_global();
+ SILC_VERIFY(schedule);
+ if (!schedule) {
+ silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
+ return FALSE;
+ }
+ }
+
SILC_SCHEDULE_LOCK(schedule);
/* Delete from fd queue */
if (fd)
return silc_schedule_task_del_by_fd(schedule, fd);
+ if (!schedule) {
+ schedule = silc_schedule_get_global();
+ SILC_VERIFY(schedule);
+ if (!schedule) {
+ silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
+ return FALSE;
+ }
+ }
+
SILC_SCHEDULE_LOCK(schedule);
/* Delete from timeout queue */
{
SilcTaskFd task;
+ if (!schedule) {
+ schedule = silc_schedule_get_global();
+ SILC_VERIFY(schedule);
+ if (!schedule) {
+ silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
+ return FALSE;
+ }
+ }
+
if (silc_unlikely(!schedule->valid)) {
silc_set_errno(SILC_ERR_NOT_VALID);
return FALSE;
SilcTaskFd task;
SilcTaskEvent event = 0;
+ if (!schedule) {
+ schedule = silc_schedule_get_global();
+ SILC_VERIFY(schedule);
+ if (!schedule) {
+ silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
+ return 0;
+ }
+ }
+
if (silc_unlikely(!schedule->valid)) {
silc_set_errno(SILC_ERR_NOT_VALID);
return 0;
void silc_schedule_set_notify(SilcSchedule schedule,
SilcTaskNotifyCb notify, void *context);
+/****f* silcutil/SilcScheduleAPI/silc_schedule_set_global
+ *
+ * SYNOPSIS
+ *
+ * void silc_schedule_set_global(SilcSchedule schedule);
+ *
+ * DESCRIPTION
+ *
+ * Sets global SilcSchedule `schedule' that can be retrieved at any time
+ * by using silc_schedule_get_global. The global scheduler is global only
+ * to the current thread. Each thread can have their own global scheduler.
+ * If each thread must have global scheduler this must be called in each
+ * thread. If the global scheduler has been set already, new call will
+ * replace the old one.
+ *
+ * This routine is provided only as a convenience function to store
+ * program's or thread's scheduler in one global place. It is not mandatory
+ * to call this function in order to use SilcSchedule.
+ *
+ * Many routines that require SilcSchedule as an argument will call
+ * silc_schedule_get_global if the scheduler is not provided to try to
+ * get global scheduler. Almost all routines in SilcSchedule API will call
+ * silc_schedule_get_global if the SilcSchedule is not provided as argument.
+ *
+ ***/
+void silc_schedule_set_global(SilcSchedule schedule);
+
+/****f* silcutil/SilcScheduleAPI/silc_schedule_get_global
+ *
+ * SYNOPSIS
+ *
+ * SilcSchedule silc_schedule_get_global(void);
+ *
+ * DESCRIPTION
+ *
+ * Returns the thread's global scheduler that was set by calling
+ * silc_schedule_set_global or NULL if global scheduler has not been set.
+ *
+ ***/
+SilcSchedule silc_schedule_get_global(void);
+
/****f* silcutil/SilcScheduleAPI/silc_schedule_task_add_fd
*
* SYNOPSIS
* This returns the new task or NULL on error. If a task with `fd' has
* already been added this will return the existing task pointer.
*
+ * If `schedule' is NULL this will call silc_schedule_get_global to try to
+ * get global scheduler.
+ *
***/
#define silc_schedule_task_add_fd(schedule, fd, callback, context) \
silc_schedule_task_add(schedule, fd, callback, context, 0, 0, SILC_TASK_FD)
* to the `callback' is SILC_TASK_EXPIRE. A task added with zero (0)
* timeout will be executed immediately next time tasks are scheduled.
*
+ * If `schedule' is NULL this will call silc_schedule_get_global to try to
+ * get global scheduler.
+ *
***/
#define silc_schedule_task_add_timeout(schedule, callback, context, s, u) \
silc_schedule_task_add(schedule, 0, callback, context, s, u, \
* effect when called. The event delivered to the `callback' is
* SILC_TASK_INTERRUPT.
*
+ * If `schedule' is NULL this will call silc_schedule_get_global to try to
+ * get global scheduler.
+ *
* NOTES
*
* One signal may be registered only one callback. Adding second callback
* in task callbacks (including in the task's own task callback) and
* in multi-threaded environment in other threads as well.
*
+ * If `schedule' is NULL this will call silc_schedule_get_global to try to
+ * get global scheduler.
+ *
***/
SilcBool silc_schedule_task_del(SilcSchedule schedule, SilcTask task);
* in task callbacks (including in the task's own task callback) and
* in multi-threaded environment in other threads as well.
*
+ * If `schedule' is NULL this will call silc_schedule_get_global to try to
+ * get global scheduler.
+ *
***/
SilcBool silc_schedule_task_del_by_fd(SilcSchedule schedule, SilcUInt32 fd);
* in task callbacks (including in the task's own task callback) and
* in multi-threaded environment in other threads as well.
*
+ * If `schedule' is NULL this will call silc_schedule_get_global to try to
+ * get global scheduler.
+ *
***/
SilcBool silc_schedule_task_del_by_callback(SilcSchedule schedule,
SilcTaskCallback callback);
* in task callbacks (including in the task's own task callback) and
* in multi-threaded environment in other threads as well.
*
+ * If `schedule' is NULL this will call silc_schedule_get_global to try to
+ * get global scheduler.
+ *
***/
SilcBool silc_schedule_task_del_by_context(SilcSchedule schedule,
void *context);
* in task callbacks (including in the task's own task callback) and
* in multi-threaded environment in other threads as well.
*
+ * If `schedule' is NULL this will call silc_schedule_get_global to try to
+ * get global scheduler.
+ *
***/
SilcBool silc_schedule_task_del_by_all(SilcSchedule schedule, int fd,
SilcTaskCallback callback,
* after the event occurs in reality. In normal cases the `send_events'
* is set to FALSE.
*
+ * If `schedule' is NULL this will call silc_schedule_get_global to try to
+ * get global scheduler.
+ *
* Returns FALSE if the operation could not performed and TRUE if it
* was a success.
*
* Returns the file descriptor `fd' current requested events mask,
* or 0 on error.
*
+ * If `schedule' is NULL this will call silc_schedule_get_global to try to
+ * get global scheduler.
+ *
***/
SilcTaskEvent silc_schedule_get_fd_events(SilcSchedule schedule,
SilcUInt32 fd);
* file descriptor `fd'. No events will be detected for the `fd'
* after calling this function.
*
+ * If `schedule' is NULL this will call silc_schedule_get_global to try to
+ * get global scheduler.
+ *
***/
void silc_schedule_unset_listen_fd(SilcSchedule schedule, SilcUInt32 fd);
SilcSocketStream stream;
SilcSocketHostLookup l;
- if (!sock || !schedule) {
- SILC_LOG_ERROR(("Missing arguments to silc_socket_tcp_stream_create"));
+ if (!schedule) {
+ schedule = silc_schedule_get_global();
+ if (!schedule) {
+ silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
+ if (callback)
+ callback(silc_errno, NULL, context);
+ return NULL;
+ }
+ }
+
+ if (!sock) {
+ silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
if (callback)
- callback(SILC_ERR_INVALID_ARGUMENT, NULL, context);
+ callback(silc_errno, NULL, context);
return NULL;
}
{
SilcSocketStream stream;
+ if (!schedule) {
+ schedule = silc_schedule_get_global();
+ if (!schedule) {
+ silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
+ return NULL;
+ }
+ }
+
stream = silc_calloc(1, sizeof(*stream));
if (!stream)
return NULL;
* also return NULL as the `callback' is called immediately.
*
* If the silc_stream_set_notifier is called the stream is set to
- * non-blocking mode.
+ * non-blocking mode. If `schedule' is NULL this will call
+ * silc_schedule_get_global to try to get global scheduler.
*
***/
SilcAsyncOperation
* This function returns the created SilcStream or NULL on error.
*
* If the silc_stream_set_notifier is called the stream is set to
- * non-blocking mode.
+ * non-blocking mode. If `schedule' is NULL this will call
+ * silc_schedule_get_global to try to get global scheduler.
*
***/
SilcStream silc_socket_udp_stream_create(SilcSocket sock,
* If `notifier' is set to NULL no callback will be called for the stream,
* and the stream is not scheduled anymore.
*
- * This function returns FALSE if the `schedule' was provided and the
- * stream could not be scheduled. The actual API for `stream' may provide
- * access to the actual error information. Returns TRUE on success.
+ * This function returns FALSE if the stream could not be scheduled.
+ * Returns TRUE on success. The `schedule' must always be non-NULL.
*
***/
SilcBool silc_stream_set_notifier(SilcStream stream, SilcSchedule schedule,
with silc_calloc and freeable with silc_free, and must also be able to
pre-allocate from stack. */
typedef struct SilcTlsObject {
+ SilcSchedule schedule; /* Global scheduler */
void *thread_context; /* Context set with SILC Tls API */
void *platform_context; /* Platform specific context */
char error_reason[256]; /* Reason for the error */
SILC_LOG_DEBUG(("Creating TCP listener"));
- if (port < 0 || !schedule || !callback)
+ if (!schedule) {
+ schedule = silc_schedule_get_global();
+ if (!schedule) {
+ silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
+ goto err;
+ }
+ }
+
+ if (port < 0 || !callback) {
+ silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
goto err;
+ }
listener = (SilcNetListener)silc_calloc(1, sizeof(*listener));
if (!listener) {
SILC_LOG_DEBUG(("Creating TCP listener"));
- if (!schedule || !callback)
+ if (!schedule) {
+ schedule = silc_schedule_get_global();
+ if (!schedule) {
+ silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
+ goto err;
+ }
+ }
+
+ if (!callback) {
+ silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
goto err;
+ }
listener = (SilcNetListener)silc_calloc(1, sizeof(*listener));
if (!listener) {
SilcResult status;
TInt ret;
- if (!remote_ip_addr || remote_port < 1 || !schedule || !callback)
+ if (!schedule) {
+ schedule = silc_schedule_get_global();
+ if (!schedule) {
+ silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
+ return NULL;
+ }
+ }
+
+ if (!remote_ip_addr || remote_port < 1 || !callback) {
+ silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
return NULL;
+ }
SILC_LOG_DEBUG(("Creating connection to host %s port %d",
remote_ip_addr, remote_port));
SILC_LOG_DEBUG(("Creating UDP stream"));
- if (!schedule)
- goto err;
+ if (!schedule) {
+ schedule = silc_schedule_get_global();
+ if (!schedule) {
+ silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
+ goto err;
+ }
+ }
SILC_LOG_DEBUG(("Binding to local address %s",
local_ip_addr ? local_ip_addr : "0.0.0.0"));
SILC_LOG_DEBUG(("Creating TCP listener"));
- if (port < 0 || !schedule || !callback) {
+ if (!schedule) {
+ schedule = silc_schedule_get_global();
+ if (!schedule) {
+ silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
+ goto err;
+ }
+ }
+
+ if (port < 0 || !callback) {
silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
goto err;
}
SILC_LOG_DEBUG(("Creating TCP listener"));
- if (!schedule || !callback) {
+ if (!schedule) {
+ schedule = silc_schedule_get_global();
+ if (!schedule) {
+ silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
+ goto err;
+ }
+ }
+
+ if (!callback) {
silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
goto err;
}
SILC_LOG_DEBUG(("Creating UDP stream"));
if (!schedule) {
- silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
- goto err;
+ schedule = silc_schedule_get_global();
+ if (!schedule) {
+ silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
+ goto err;
+ }
}
/* Bind to local addresses */
{
SilcNetConnect conn;
- if (!remote_ip_addr || remote_port < 1 || !schedule || !callback)
+ if (!schedule) {
+ schedule = silc_schedule_get_global();
+ if (!schedule) {
+ silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
+ return NULL;
+ }
+ }
+
+ if (!remote_ip_addr || remote_port < 1 || !callback) {
+ silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
return NULL;
+ }
SILC_LOG_DEBUG(("Creating connection to host %s port %d",
remote_ip_addr, remote_port));
SILC_LOG_DEBUG(("Creating TCP listener"));
- if (port < 0 || !schedule || !callback) {
+ if (!schedule) {
+ schedule = silc_schedule_get_global();
+ if (!schedule) {
+ silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
+ goto err;
+ }
+ }
+
+ if (port < 0 || !callback) {
silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
goto err;
}
SILC_LOG_DEBUG(("Creating TCP listener"));
- if (!schedule || !callback) {
+ if (!schedule) {
+ schedule = silc_schedule_get_global();
+ if (!schedule) {
+ silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
+ goto err;
+ }
+ }
+
+ if (!callback) {
silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
goto err;
}
SILC_LOG_DEBUG(("Creating UDP stream"));
- if (!schedule)
- goto err;
+ if (!schedule) {
+ schedule = silc_schedule_get_global();
+ if (!schedule) {
+ silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
+ goto err;
+ }
+ }
/* Bind to local addresses */
SILC_LOG_DEBUG(("Binding to local address %s",
{
SilcNetConnect conn;
- if (!remote_ip_addr || remote_port < 1 || !schedule || !callback) {
+ if (!schedule) {
+ schedule = silc_schedule_get_global();
+ if (!schedule) {
+ silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
+ return NULL;
+ }
+ }
+
+ if (!remote_ip_addr || remote_port < 1 || !callback) {
silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
return NULL;
}