Added silc_schedule_[set|get]_global. Added many APIs to call
authorPekka Riikonen <priikone@silcnet.org>
Wed, 26 Dec 2007 11:55:43 +0000 (11:55 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Wed, 26 Dec 2007 11:55:43 +0000 (11:55 +0000)
silc_schedule_get_global if provided scheduler argument is NULL.

22 files changed:
CHANGES.RUNTIME
TODO
lib/silchttp/silchttpserver.c
lib/silchttp/silchttpserver.h
lib/silcsftp/sftp_client.c
lib/silcsftp/sftp_server.c
lib/silcsftp/silcsftp.h
lib/silcutil/silcfsm.c
lib/silcutil/silcfsm.h
lib/silcutil/silclog.c
lib/silcutil/silclog.h
lib/silcutil/silcnet.c
lib/silcutil/silcnet.h
lib/silcutil/silcschedule.c
lib/silcutil/silcschedule.h
lib/silcutil/silcsocketstream.c
lib/silcutil/silcsocketstream.h
lib/silcutil/silcstream.h
lib/silcutil/silcthread_i.h
lib/silcutil/symbian/silcsymbiannet.cpp
lib/silcutil/unix/silcunixnet.c
lib/silcutil/win32/silcwin32net.c

index ff6ebd8a0e261608dbbab00d7fd9985667b60426..05b131c5ba8866fe7d941d242c05f9a6bddaf74b 100644 (file)
@@ -1,3 +1,11 @@
+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
diff --git a/TODO b/TODO
index fd6156b4ccd834bed26fbf47a3f60039cebdc696..31f8c01ad9fed1d0aef0042d33b8f931a3147b3d 100644 (file)
--- a/TODO
+++ b/TODO
@@ -105,6 +105,8 @@ Runtime library, lib/silcutil/
 
  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:
@@ -391,16 +393,14 @@ SILC Accelerator Library
          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
 
index f43b26a354d8fd0703d82beab9929246e57586df..510d51b03ec3ad7621d105bec5e11322483d1255 100644 (file)
@@ -457,6 +457,9 @@ SilcHttpServer silc_http_server_alloc(const char *ip, SilcUInt16 port,
 
   SILC_LOG_DEBUG(("Start HTTP server at %s:%d", ip, port));
 
+  if (!schedule)
+    schedule = silc_schedule_get_global();
+
   if (!ip || !schedule || !callback)
     return FALSE;
 
index cfc87c1590dfb7d491e3d3815b647325e6b55b59..36faf5a5dc70b0229e8ec98292b03bc469bbeafb 100644 (file)
@@ -4,7 +4,7 @@
 
   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
@@ -112,6 +112,8 @@ typedef void (*SilcHttpServerCallback)(SilcHttpServer httpd,
  *    `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,
index 59f7dfb61a29ce9ad9d9d8df216d3a45c31967df..10eb160cbcbdf0ee7839960655a92197c0721ec6 100644 (file)
@@ -403,6 +403,9 @@ SilcSFTP silc_sftp_client_start(SilcStream stream,
 
   SILC_LOG_DEBUG(("Starting SFTP client"));
 
+  if (!schedule)
+    schedule = silc_schedule_get_global();
+
   if (!stream)
     return NULL;
 
index 549751e8aecc9cd3488b207f6e9dfdacf2c39794..b22e21fba5c8c55e80aee0411be951c5193f3a11 100644 (file)
@@ -361,6 +361,9 @@ SilcSFTP silc_sftp_server_start(SilcStream stream,
 {
   SilcSFTPServer server;
 
+  if (!schedule)
+    schedule = silc_schedule_get_global();
+
   server = silc_calloc(1, sizeof(*server));
   if (!server)
     return NULL;
index 5a2702fcb19c86ed0b234525de32b90347b32124..d2364146c79f39c5f0254ce317efb6930748471f 100644 (file)
@@ -410,6 +410,9 @@ typedef void (*SilcSFTPExtendedCallback)(SilcSFTP sftp,
  *    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,
@@ -874,6 +877,9 @@ void silc_sftp_extended(SilcSFTP sftp,
  *    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,
index 4ff23bab02fdb2b8eb60678629e136c9c3e5c28e..5e6fe2a5c7e001705c93255a160c7832e9baf3b2 100644 (file)
@@ -59,8 +59,11 @@ SilcBool silc_fsm_init(SilcFSM fsm,
                       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;
index c723bad0672fb4912b616020c0912ee1a13d005a..366edf704406b3cd48033f8d833279f7b1fdda1c 100644 (file)
@@ -403,7 +403,9 @@ do {                                                \
  *    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
  *
@@ -449,7 +451,9 @@ SilcFSM silc_fsm_alloc(void *fsm_context,
  *    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
  *
@@ -482,7 +486,8 @@ SilcBool silc_fsm_init(SilcFSM fsm,
  *    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
  *
index 267e7305619af43d593d8c1f2412444cb201bf73..d0bec0c1c4320c5e45cc7cec183f5614b0f4c6c9 100644 (file)
@@ -243,6 +243,9 @@ SilcBool silc_log_set_file(SilcLogType type, char *filename,
   FILE *fp = NULL;
   SilcLog log;
 
+  if (!scheduler)
+    scheduler = silc_schedule_get_global();
+
   log = silc_log_get_context(type);
   if (!log)
     return FALSE;
index 80db7783cc046fc26fc4cb50ecc146d91958b605..56c58ec345691f9b74964a78ebcc7d541d644d5b 100644 (file)
@@ -4,7 +4,7 @@
 
   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
@@ -346,8 +346,8 @@ typedef SilcBool (*SilcLogHexdumpCb)(char *file, char *function, int line,
  * SYNOPSIS
  *
  *    SilcBool silc_log_set_file(SilcLogType type, char *filename,
- *                           SilcUInt32 maxsize,
- *                           SilcSchedule scheduler);
+ *                               SilcUInt32 maxsize,
+ *                               SilcSchedule scheduler);
  *
  * DESCRIPTION
  *
@@ -359,7 +359,8 @@ typedef SilcBool (*SilcLogHexdumpCb)(char *file, char *function, int line,
  *    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,
index d2121556ef91c77372556f591d329279794ead7f..edd982a6ccfed5b7e50bc2c42320835c5002b9e2 100644 (file)
@@ -300,6 +300,11 @@ void silc_net_gethostbyname_async(const char *name,
 {
   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;
@@ -356,6 +361,11 @@ void silc_net_gethostbyaddr_async(const char *addr,
 {
   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;
index 4d44ecedadbcf1afe50818547fad72115070966c..b8db06f8fc4e382905045600648f0e5d2c88a964 100644 (file)
@@ -98,7 +98,8 @@ typedef void (*SilcNetCallback)(SilcResult status,
  *    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
@@ -136,7 +137,8 @@ silc_net_tcp_create_listener(const char **local_ip_addr,
  *    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
@@ -238,7 +240,8 @@ void silc_net_close_listener(SilcNetListener listener);
  *    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,
@@ -277,7 +280,8 @@ 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
  *
@@ -532,7 +536,8 @@ SilcBool silc_net_gethostbyname(const char *name, SilcBool prefer_ipv6,
  *    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
@@ -577,7 +582,8 @@ SilcBool silc_net_gethostbyaddr(const char *addr, char *name,
  *    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,
index d2ad0c924ccac83c9b124e9485bea30b5b42d470..476d11f1031e3518b39442dab2a7fe31b1242dc8 100644 (file)
@@ -290,14 +290,14 @@ void silc_schedule_stats(SilcSchedule schedule)
 {
   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));
@@ -376,6 +376,8 @@ SilcBool silc_schedule_uninit(SilcSchedule schedule)
 {
   SilcTask task;
 
+  SILC_VERIFY(schedule);
+
   SILC_LOG_DEBUG(("Uninitializing scheduler %p", schedule));
 
   if (schedule->valid == TRUE)
@@ -420,6 +422,7 @@ SilcBool silc_schedule_uninit(SilcSchedule schedule)
 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);
@@ -575,6 +578,39 @@ void silc_schedule_set_notify(SilcSchedule 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,
@@ -584,6 +620,15 @@ 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;
@@ -730,6 +775,15 @@ SilcTask silc_schedule_task_add(SilcSchedule schedule, SilcUInt32 fd,
 
 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;
 
@@ -787,6 +841,15 @@ SilcBool silc_schedule_task_del_by_fd(SilcSchedule schedule, SilcUInt32 fd)
 
   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 */
@@ -829,6 +892,15 @@ SilcBool silc_schedule_task_del_by_callback(SilcSchedule schedule,
 
   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 */
@@ -882,6 +954,15 @@ SilcBool silc_schedule_task_del_by_context(SilcSchedule schedule,
 
   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 */
@@ -939,6 +1020,15 @@ SilcBool silc_schedule_task_del_by_all(SilcSchedule schedule, int fd,
   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 */
@@ -973,6 +1063,15 @@ SilcBool silc_schedule_set_listen_fd(SilcSchedule schedule, SilcUInt32 fd,
 {
   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;
@@ -1012,6 +1111,15 @@ SilcTaskEvent silc_schedule_get_fd_events(SilcSchedule schedule,
   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;
index a7914aec3039be88a19bbddb6f7d648443ad6e25..af2c8cf3d336877212e1a940736ee5333c1c4fb9 100644 (file)
@@ -424,6 +424,47 @@ SilcStack silc_schedule_get_stack(SilcSchedule schedule);
 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
@@ -445,6 +486,9 @@ void silc_schedule_set_notify(SilcSchedule schedule,
  *    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)
@@ -466,6 +510,9 @@ void silc_schedule_set_notify(SilcSchedule schedule,
  *    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,         \
@@ -487,6 +534,9 @@ void silc_schedule_set_notify(SilcSchedule schedule,
  *    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
@@ -517,6 +567,9 @@ void silc_schedule_set_notify(SilcSchedule schedule,
  *    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);
 
@@ -536,6 +589,9 @@ 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);
 
@@ -556,6 +612,9 @@ 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);
@@ -576,6 +635,9 @@ SilcBool silc_schedule_task_del_by_callback(SilcSchedule schedule,
  *    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);
@@ -597,6 +659,9 @@ SilcBool silc_schedule_task_del_by_context(SilcSchedule schedule,
  *    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,
@@ -627,6 +692,9 @@ SilcBool silc_schedule_task_del_by_all(SilcSchedule schedule, int fd,
  *    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.
  *
@@ -646,6 +714,9 @@ SilcBool silc_schedule_set_listen_fd(SilcSchedule schedule, SilcUInt32 fd,
  *    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);
@@ -662,6 +733,9 @@ SilcTaskEvent silc_schedule_get_fd_events(SilcSchedule schedule,
  *    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);
 
index 5e3357433f3b7120114ca103d1f13c891bf6f073..e11fff73a5a5b29fdd1922b6d1b2b60476fedc97 100644 (file)
@@ -152,10 +152,20 @@ silc_socket_tcp_stream_create(SilcSocket sock, SilcBool lookup,
   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;
   }
 
@@ -219,6 +229,14 @@ SilcStream silc_socket_udp_stream_create(SilcSocket sock, SilcBool ipv6,
 {
   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;
index 42990936f8bf73b3f378f437e9d51d34d719b0e7..46cce4faede773f7accd4678d7eceab457d746f6 100644 (file)
@@ -93,7 +93,8 @@ typedef void (*SilcSocketStreamCallback)(SilcResult status,
  *    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
@@ -136,7 +137,8 @@ silc_socket_tcp_stream_create(SilcSocket sock, SilcBool lookup,
  *    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,
index 8195a15f3c547c8d8dadb098ec6e7cb746ba3687..85364d2a08cd316127ffeedd689738e99736f52d 100644 (file)
@@ -251,9 +251,8 @@ void silc_stream_destroy(SilcStream stream);
  *    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,
index c67fce0824c8a128bd17244375afe7b05929364a..dfccc4f669faaf48e63902104a01dcae6dcbf3ee 100644 (file)
@@ -29,6 +29,7 @@
    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 */
index 1895b1dda42aa80fe923ef239d5a1227bc7d475b..c665b3d339632fb6655a6b0484f2e726c1e1def3 100644 (file)
@@ -181,8 +181,18 @@ silc_net_tcp_create_listener(const char **local_ip_addr,
 
   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) {
@@ -301,8 +311,18 @@ silc_net_tcp_create_listener2(const char *local_ip_addr, int *ports,
 
   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) {
@@ -600,8 +620,18 @@ SilcAsyncOperation silc_net_tcp_connect(const char *local_ip_addr,
   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));
@@ -727,8 +757,13 @@ SilcStream silc_net_udp_connect(const char *local_ip_addr, int local_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"));
index de7eeaee881d333af97733a7747d21f275bbc8bf..15720dcd53691f8903f6141776aaf7ac636fbb7f 100644 (file)
@@ -143,7 +143,15 @@ silc_net_tcp_create_listener(const char **local_ip_addr,
 
   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;
   }
@@ -253,7 +261,15 @@ silc_net_tcp_create_listener2(const char *local_ip_addr, int *ports,
 
   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;
   }
@@ -397,8 +413,11 @@ silc_net_udp_connect(const char *local_ip_addr, int local_port,
   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 */
@@ -872,8 +891,18 @@ SilcAsyncOperation silc_net_tcp_connect(const char *local_ip_addr,
 {
   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));
index 0aba454f50edcc9e0ba0694a961a8971c62f667d..0501ab82d12b62873471491773133528edfc6164 100644 (file)
@@ -145,7 +145,15 @@ silc_net_tcp_create_listener(const char **local_ip_addr,
 
   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;
   }
@@ -254,7 +262,15 @@ silc_net_tcp_create_listener2(const char *local_ip_addr, int *ports,
 
   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;
   }
@@ -398,8 +414,13 @@ silc_net_udp_connect(const char *local_ip_addr, int local_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;
+    }
+  }
 
   /* Bind to local addresses */
   SILC_LOG_DEBUG(("Binding to local address %s",
@@ -797,7 +818,15 @@ SilcAsyncOperation silc_net_tcp_connect(const char *local_ip_addr,
 {
   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;
   }