updates.
authorPekka Riikonen <priikone@silcnet.org>
Sat, 23 Jun 2001 13:20:39 +0000 (13:20 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Sat, 23 Jun 2001 13:20:39 +0000 (13:20 +0000)
21 files changed:
CHANGES
acconfig.h.pre
apps/irssi/src/silc/core/silc-core.c
apps/silcd/packet_send.c
apps/silcd/server.c
apps/silcd/server_internal.h
configure.in.pre
distributions
includes/silcincludes.h
lib/silcclient/client.c
lib/silcclient/client.h
lib/silcclient/client_keyagr.c
lib/silccore/silccommand.c
lib/silccore/silccommand.h
lib/silcutil/Makefile.am
lib/silcutil/silcschedule.h
lib/silcutil/silctask.c
lib/silcutil/silctask.h
lib/silcutil/unix/Makefile.am [new file with mode: 0644]
lib/silcutil/unix/silcunixschedule.c [moved from lib/silcutil/silcschedule.c with 63% similarity]
lib/silcutil/win32/Makefile.am [new file with mode: 0644]

diff --git a/CHANGES b/CHANGES
index fe89869cb886edd86a4e2ba32cb05cbf34c28116..aa885ab0e18d030418cb9c75fa28788f82648b6e 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,17 @@
+Sat Jun 23 16:01:00 EEST 2001  Pekka Riikonen <priikone@silcnet.org>
+
+       * Added preliminary support for native WIN32 compilation under
+         cygwin (using the -mno-cygwin option for GCC) to the
+         ./configure.in.pre.  The --with-win32 now prepares the
+         compilation for native WIN32.
+
+       * Rewrote the SILC Scheduler interface in the file
+         lib/silcutil/silcschedule.h.  The scheduler is not context
+         based and does not have anymore any global static scheduler.
+         Moved the Unix scheduler to the lib/silcutil/unix/ directory
+         and created lib/silcutil/win32 directory for WIN32 based
+         scheduler.
+
 Fri Jun 22 10:44:14 EEST 2001  Pekka Riikonen <priikone@silcnet.org>
 
        * Do not handle JOIN notify in the server if the target client
index 340d8308d1289466c3dc9b13de87eb261d4e8b6a..ce215431461d49c95a94cbe454d03ff436f29a58 100644 (file)
@@ -68,4 +68,8 @@
 #undef Rfclose
 #undef Rgethostbyname
 
+/* Native WIN32 compilation (-mno-cygwin GCC option) under cygwin, though
+   the code compiles with any native WIN32 compiler. */
+#undef SILC_WIN32
+
 /* SILC distribution definitions (leave this at the end of file) */
index 787290ccfa8556807779485a086b857ac37730b3..0c80e52ac703724ae9ed1ae75349ba4e9aa35d12 100644 (file)
@@ -66,7 +66,7 @@ uint32 sims_count = 0;
 
 static int my_silc_scheduler(void)
 {
-  silc_schedule_one(0);
+  silc_schedule_one(silc_client->schedule, 0);
   return 1;
 }
 
index 46a77f18c453d3fb65b3645cd7375fc9d6ffd9f8..81cdce5259489f4fafba35d7c302a6718bc2a1fb 100644 (file)
@@ -49,7 +49,7 @@ int silc_server_packet_send_real(SilcServer server,
      This call sets the connection both for input and output (the input
      is set always and this call keeps the input setting, actually). 
      Actual data sending is performed by silc_server_packet_process. */
-  SILC_SET_CONNECTION_FOR_OUTPUT(sock->sock);
+  SILC_SET_CONNECTION_FOR_OUTPUT(server->schedule, sock->sock);
 
   /* Mark to socket that data is pending in outgoing buffer. This flag
      is needed if new data is added to the buffer before the earlier
index ef90e6dc1d731083a5b6ba1072f510afd2974168..4dde2b3669afbcfe10142922138560469e23b234 100644 (file)
@@ -267,30 +267,20 @@ int silc_server_init(SilcServer server)
     server->id_entry = id_entry;
   }
 
-  /* Register the task queues. In SILC we have by default three task queues. 
-     One task queue for non-timeout tasks which perform different kind of 
-     I/O on file descriptors, timeout task queue for timeout tasks, and,
-     generic non-timeout task queue whose tasks apply to all connections. */
-  silc_task_queue_alloc(&server->io_queue, TRUE);
-  if (!server->io_queue) {
-    goto err0;
-  }
-  silc_task_queue_alloc(&server->timeout_queue, TRUE);
-  if (!server->timeout_queue) {
-    goto err1;
-  }
-  silc_task_queue_alloc(&server->generic_queue, TRUE);
-  if (!server->generic_queue) {
-    goto err1;
-  }
-
   /* Register protocols */
   silc_server_protocols_register();
 
-  /* Initialize the scheduler */
-  silc_schedule_init(&server->io_queue, &server->timeout_queue, 
-                    &server->generic_queue, 
-                    SILC_SERVER_MAX_CONNECTIONS);
+  /* Initialize the scheduler. This will register the task queues as well.
+     In SILC we have by default three task queues. One task queue for
+     non-timeout tasks which perform different kind of I/O on file
+     descriptors, timeout task queue for timeout tasks, and, generic
+     non-timeout task queue whose tasks apply to all connections. */
+  server->schedule = silc_schedule_init(&server->io_queue, 
+                                       &server->timeout_queue, 
+                                       &server->generic_queue, 
+                                       SILC_SERVER_MAX_CONNECTIONS);
+  if (!server->schedule)
+    goto err0;
   
   /* Add the first task to the queue. This is task that is executed by
      timeout. It expires as soon as the caller calls silc_server_run. This
@@ -342,9 +332,6 @@ int silc_server_init(SilcServer server)
   /* We are done here, return succesfully */
   return TRUE;
 
-  silc_task_queue_free(server->timeout_queue);
- err1:
-  silc_task_queue_free(server->io_queue);
  err0:
   for (i = 0; i < sock_count; i++)
     silc_net_close_server(sock[i]);
@@ -467,8 +454,8 @@ void silc_server_stop(SilcServer server)
   /* Stop the scheduler, although it might be already stopped. This
      doesn't hurt anyone. This removes all the tasks and task queues,
      as well. */
-  silc_schedule_stop();
-  silc_schedule_uninit();
+  silc_schedule_stop(server->schedule);
+  silc_schedule_uninit(server->schedule);
 
   silc_server_protocols_unregister();
 
@@ -487,7 +474,7 @@ void silc_server_run(SilcServer server)
 
   /* Start the scheduler, the heart of the SILC server. When this returns
      the program will be terminated. */
-  silc_schedule();
+  silc_schedule(server->schedule);
 }
 
 /* Timeout callback that will be called to retry connecting to remote
@@ -1404,7 +1391,7 @@ SILC_TASK_CALLBACK(silc_server_packet_process)
        back to only for input. When there is again some outgoing data 
        available for this connection it will be set for output as well. 
        This call clears the output setting and sets it only for input. */
-    SILC_SET_CONNECTION_FOR_INPUT(fd);
+    SILC_SET_CONNECTION_FOR_INPUT(server->schedule, fd);
     SILC_UNSET_OUTBUF_PENDING(sock);
 
     silc_buffer_clear(sock->outbuf);
@@ -2089,7 +2076,7 @@ void silc_server_close_connection(SilcServer server,
   }
 
   /* We won't listen for this connection anymore */
-  silc_schedule_unset_listen_fd(sock->sock);
+  silc_schedule_unset_listen_fd(server->schedule, sock->sock);
 
   /* Unregister all tasks */
   silc_task_unregister_by_fd(server->io_queue, sock->sock);
@@ -2177,7 +2164,7 @@ void silc_server_free_client_data(SilcServer server,
 
     silc_packet_send(sock, TRUE);
 
-    SILC_SET_CONNECTION_FOR_INPUT(sock->sock);
+    SILC_SET_CONNECTION_FOR_INPUT(server->schedule, sock->sock);
     SILC_UNSET_OUTBUF_PENDING(sock);
     silc_buffer_clear(sock->outbuf);
   }
index 1de43890672c3e09ca8816ec55be816bf78fdc84..24942e378d23f4158ae4ebee0c6bf9b9bb57a3cd 100644 (file)
@@ -95,7 +95,8 @@ struct SilcServerStruct {
   /* Back pointer to the primary router of this server. */
   SilcServerEntry router;
 
-  /* SILC server task queues */
+  /* SILC server schduler and task queues */
+  SilcSchedule schedule;
   SilcTaskQueue io_queue;
   SilcTaskQueue timeout_queue;
   SilcTaskQueue generic_queue;
@@ -160,13 +161,6 @@ typedef struct {
   uint32 failure;
 } *SilcServerFailureContext;
 
-/* Session key's re-key context. */
-typedef struct {
-  SilcServer server;
-  SilcSocketConnection sock;
-  uint32 timeout;
-} *SilcServerRekeyContext;
-
 /* Macros */
 
 /* Registers generic task for file descriptor for reading from network and
@@ -182,15 +176,15 @@ do {                                                                      \
   silc_task_set_iotype(tmptask, SILC_TASK_WRITE);                      \
 } while(0)
 
-#define SILC_SET_CONNECTION_FOR_INPUT(fd)                              \
+#define SILC_SET_CONNECTION_FOR_INPUT(s, fd)                           \
 do {                                                                   \
-  silc_schedule_set_listen_fd((fd), (1L << SILC_TASK_READ));            \
+  silc_schedule_set_listen_fd((s), (fd), (1L << SILC_TASK_READ));      \
 } while(0)
      
-#define SILC_SET_CONNECTION_FOR_OUTPUT(fd)                             \
+#define SILC_SET_CONNECTION_FOR_OUTPUT(s, fd)                          \
 do {                                                                   \
-  silc_schedule_set_listen_fd((fd), ((1L << SILC_TASK_READ) |           \
-                                    (1L << SILC_TASK_WRITE)));         \
+  silc_schedule_set_listen_fd((s), (fd), ((1L << SILC_TASK_READ) |     \
+                                    (1L << SILC_TASK_WRITE)));         \
 } while(0)
 
 /* Prototypes */
index 082a617382f924bb0c7d98978ea88601eb8867fa..293fa1e99a1b2ca27c5bdc092681f849730c4d49 100644 (file)
@@ -105,14 +105,6 @@ AC_DEFUN(AC_CHECK_CURSES,[
        AC_SUBST(CURSES_LIBS)
        AC_SUBST(CURSES_INCLUDEDIR)
 
-       AC_ARG_WITH(sco,
-         [  --with-sco              Use this to turn on SCO-specific code],[
-         if test x$withval = xyes; then
-               AC_DEFINE(SCO_FLAVOR)
-               CFLAGS="$CFLAGS -D_SVID3"
-         fi
-       ])
-
        AC_ARG_WITH(sunos-curses,
          [  --with-sunos-curses     Used to force SunOS 4.x curses],[
          if test x$withval = xyes; then
@@ -419,23 +411,6 @@ AC_ARG_WITH(logsdir,
 AC_SUBST(LOGSDIR)
 AC_DEFINE_UNQUOTED(SILC_LOGSDIR, "$LOGSDIR")
 
-# Debug checking
-AC_MSG_CHECKING(for enabled debugging)
-AC_ARG_ENABLE(debug,
-[  --enable-debug          Enable debugging (warning: it is heavy!)],
-[ case "${enableval}" in
-  yes) 
-    AC_MSG_RESULT(yes)
-    AC_DEFINE(SILC_DEBUG)
-    CFLAGS="-O -g $CFLAGS"
-    ;;
-  *)
-    AC_MSG_RESULT(no)
-    CFLAGS="-O2 -g $CFLAGS"
-    ;;
-esac ], CFLAGS="-O2 -g $CFLAGS"
-        AC_MSG_RESULT(no))
-
 # SOCKS4 support checking
 AC_MSG_CHECKING(whether to support SOCKS4)
 AC_ARG_WITH(socks4,
@@ -561,6 +536,30 @@ AC_ARG_WITH(silcd-config-file,
                           server [/etc/silc/silcd.conf]],
 [ AC_DEFINE_UNQUOTED(SILC_SERVER_CONFIG_FILE, "$withval") ])
 
+# Native WIN32 compilation under cygwin
+AC_ARG_WITH(win32,
+[  --with-win32            Compile native WIN32 code (-mno-cygwin)],
+[ AC_DEFINE(SILC_WIN32)
+  AM_CONDITIONAL(SILC_WIN32, test xtrue = xtrue)
+  CFLAGS="-mno-cygwin $CFLAGS" ])
+
+# Debug checking
+AC_MSG_CHECKING(for enabled debugging)
+AC_ARG_ENABLE(debug,
+[  --enable-debug          Enable debugging (warning: it is heavy!)],
+[ case "${enableval}" in
+  yes) 
+    AC_MSG_RESULT(yes)
+    AC_DEFINE(SILC_DEBUG)
+    CFLAGS="-O -g $CFLAGS"
+    ;;
+  *)
+    AC_MSG_RESULT(no)
+    CFLAGS="-O2 -g $CFLAGS"
+    ;;
+esac ], CFLAGS="-O2 -g $CFLAGS"
+        AC_MSG_RESULT(no))
+
 #
 # Other configure scripts
 #
@@ -599,5 +598,7 @@ lib/silcsim/Makefile
 lib/silcsim/modules/Makefile
 lib/silcske/Makefile
 lib/silcutil/Makefile
+lib/silcutil/unix/Makefile
+lib/silcutil/win32/Makefile
 silc/Makefile
 silcd/Makefile)
index 35552d7eb122443ce804580fc81617494a6cb5a1..382a7c4375ba6eb66c3d04920b3bf122786a0d6a 100644 (file)
 # To prepare the distribution give command ./prepare xyz 1.0.4
 #
 
+# Default Toolkit distribution
 _toolkit_SUBDIRS=lib irssi silc silcd doc includes
 _toolkit_SUBDIRS_lib=$(COMMONDIRS)
 _toolkit_SUBDIRS_doc=$(COMMONDIRS)
 _toolkit_DISTLABEL=SILC_DIST_TOOLKIT
 
+# Irssi SILC Client distribution
 _client_SUBDIRS=lib irssi doc includes
 _client_SUBDIRS_lib=contrib silccore silccrypt silcsim silcmath silcske silcutil trq silcclient
 _client_SUBDIRS_doc=$(COMMONDIRS)
 _client_DISTLABEL=SILC_DIST_CLIENT
 
+# SILC Server distribution
 _server_SUBDIRS=lib silcd doc includes
 _server_SUBDIRS_lib=contrib silccore silccrypt silcsim silcmath silcske silcutil trq dotconf
 _server_SUBDIRS_doc=$(COMMONDIRS)
 _server_DISTLABEL=SILC_DIST_SERVER
 
-DISTRIBUTIONS=toolkit client server
+# Native WIN32 SILC library distribution (will include only the libraries)
+_win32dll_SUBDIRS=lib doc includes
+_win32dll_SUBDIRS_lib=$(COMMONDIRS)
+_win32dll_SUBDIRS_doc=$(COMMONDIRS)
+_win32dll_DISTLABEL=SILC_DIST_WIN32DLL
+
+DISTRIBUTIONS=toolkit client server win32dll
index bf9b2862b12fc772a75cf99da615c784c30492e6..f99e5e0976c25eeed17be8fc86f59d4cecb9daf1 100644 (file)
 /* Automatically generated configuration header */
 #include "silcdefs.h"
 
+#ifdef SILC_WIN32
+#include <windows.h>
+#endif
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
 #include <stdarg.h>
-#include <pwd.h>
-#include <grp.h>
-
 #include <ctype.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/time.h>
-#include <sys/times.h>
 #include <time.h>
 
-#ifdef SOCKS5
-#include "socks.h"
-#endif
-
-#ifdef HAVE_GETOPT_H
-#include <getopt.h>
-#endif
-
 #ifdef HAVE_SIGNAL_H
 #include <signal.h>
 #else
 #error assert.h not found in the system
 #endif
 
+#ifndef SILC_WIN32
+
+#include <pwd.h>
+#include <grp.h>
+#include <sys/times.h>
+
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#endif
+
+#ifdef SOCKS5
+#include "socks.h"
+#endif
+
 #include <sys/socket.h>
 #ifdef HAVE_NETINET_IN_H
 #include <netinet/in.h>
 #include <dlfcn.h>
 #endif
 
+#endif                         /* !SILC_WIN32 */
+
 #ifndef HAVE_GETOPT_LONG
 #include "../lib/contrib/getopt.h"
 #endif
index 36c4c93d50613744a23bb06b9dcaa3b658ba2bf4..dde26d5322c4f05e6a6ee2079d142d3309efa1b0 100644 (file)
@@ -87,8 +87,11 @@ int silc_client_init(SilcClient client)
   silc_client_protocols_register();
 
   /* Initialize the scheduler */
-  silc_schedule_init(&client->io_queue, &client->timeout_queue, 
-                    &client->generic_queue, 5000);
+  client->schedule = silc_schedule_init(&client->io_queue, 
+                                       &client->timeout_queue, 
+                                       &client->generic_queue, 5000);
+  if (!client->schedule)
+    return FALSE;
 
   return TRUE;
 }
@@ -103,8 +106,8 @@ void silc_client_stop(SilcClient client)
   /* Stop the scheduler, although it might be already stopped. This
      doesn't hurt anyone. This removes all the tasks and task queues,
      as well. */
-  silc_schedule_stop();
-  silc_schedule_uninit();
+  silc_schedule_stop(client->schedule);
+  silc_schedule_uninit(client->schedule);
 
   silc_client_protocols_unregister();
 
@@ -120,7 +123,7 @@ void silc_client_run(SilcClient client)
 
   /* Start the scheduler, the heart of the SILC client. When this returns
      the program will be terminated. */
-  silc_schedule();
+  silc_schedule(client->schedule);
 }
 
 /* Allocates and adds new connection to the client. This adds the allocated
@@ -247,7 +250,7 @@ silc_client_connect_to_server_internal(SilcClientInternalConnectContext *ctx)
                                 SILC_TASK_FD,
                                 SILC_TASK_PRI_NORMAL);
   silc_task_reset_iotype(ctx->task, SILC_TASK_WRITE);
-  silc_schedule_set_listen_fd(sock, ctx->task->iomask);
+  silc_schedule_set_listen_fd(ctx->client->schedule, sock, ctx->task->iomask);
 
   ctx->sock = sock;
 
@@ -377,7 +380,7 @@ SILC_TASK_CALLBACK(silc_client_connect_to_server_start)
                       ctx->port, ctx->host);
 
       /* Unregister old connection try */
-      silc_schedule_unset_listen_fd(fd);
+      silc_schedule_unset_listen_fd(client->schedule, fd);
       silc_net_close_connection(fd);
       silc_task_unregister(client->io_queue, ctx->task);
 
@@ -388,7 +391,7 @@ SILC_TASK_CALLBACK(silc_client_connect_to_server_start)
       /* Connection failed and we won't try anymore */
       client->ops->say(client, conn, "Could not connect to server %s: %s",
                       ctx->host, strerror(opt));
-      silc_schedule_unset_listen_fd(fd);
+      silc_schedule_unset_listen_fd(client->schedule, fd);
       silc_net_close_connection(fd);
       silc_task_unregister(client->io_queue, ctx->task);
       silc_free(ctx);
@@ -400,7 +403,7 @@ SILC_TASK_CALLBACK(silc_client_connect_to_server_start)
     return;
   }
 
-  silc_schedule_unset_listen_fd(fd);
+  silc_schedule_unset_listen_fd(client->schedule, fd);
   silc_task_unregister(client->io_queue, ctx->task);
   silc_free(ctx);
 
@@ -591,7 +594,7 @@ int silc_client_packet_send_real(SilcClient client,
      This call sets the connection both for input and output (the input
      is set always and this call keeps the input setting, actually). 
      Actual data sending is performed by silc_client_packet_process. */
-  SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(sock->sock);
+  SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(client->schedule, sock->sock);
 
   /* Mark to socket that data is pending in outgoing buffer. This flag
      is needed if new data is added to the buffer before the earlier
@@ -638,7 +641,7 @@ SILC_TASK_CALLBACK_GLOBAL(silc_client_packet_process)
        back to only for input. When there is again some outgoing data 
        available for this connection it will be set for output as well. 
        This call clears the output setting and sets it only for input. */
-    SILC_CLIENT_SET_CONNECTION_FOR_INPUT(fd);
+    SILC_CLIENT_SET_CONNECTION_FOR_INPUT(client->schedule, fd);
     SILC_UNSET_OUTBUF_PENDING(sock);
 
     silc_buffer_clear(sock->outbuf);
@@ -1147,7 +1150,7 @@ void silc_client_close_connection(SilcClient client,
     sock = conn->sock;
 
   /* We won't listen for this connection anymore */
-  silc_schedule_unset_listen_fd(sock->sock);
+  silc_schedule_unset_listen_fd(client->schedule, sock->sock);
 
   /* Unregister all tasks */
   silc_task_unregister_by_fd(client->io_queue, sock->sock);
index fff7d0174f3c1d26d8b63ba20afc523680880775..dd27a1467a6af1b94e66463fbc2ad92f17452fe7 100644 (file)
@@ -158,7 +158,8 @@ struct SilcClientStruct {
   /* All client operations that are implemented in the application. */
   SilcClientOperations *ops;
 
-  /* SILC client task queues */
+  /* SILC client scheduler and task queues */
+  SilcSchedule schedule;
   SilcTaskQueue io_queue;
   SilcTaskQueue timeout_queue;
   SilcTaskQueue generic_queue;
@@ -202,15 +203,15 @@ do {                                                                      \
   silc_task_set_iotype(tmptask, SILC_TASK_WRITE);                      \
 } while(0)
 
-#define SILC_CLIENT_SET_CONNECTION_FOR_INPUT(fd)               \
-do {                                                           \
-  silc_schedule_set_listen_fd((fd), (1L << SILC_TASK_READ));   \
-} while(0)                                                     \
+#define SILC_CLIENT_SET_CONNECTION_FOR_INPUT(s, fd)                    \
+do {                                                                   \
+  silc_schedule_set_listen_fd((s), (fd), (1L << SILC_TASK_READ));      \
+} while(0)
      
-#define SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(fd)              \
-do {                                                           \
-  silc_schedule_set_listen_fd((fd), ((1L << SILC_TASK_READ) |  \
-                                    (1L << SILC_TASK_WRITE))); \
+#define SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(s, fd)                   \
+do {                                                                   \
+  silc_schedule_set_listen_fd((s), (fd), ((1L << SILC_TASK_READ) |     \
+                                    (1L << SILC_TASK_WRITE)));         \
 } while(0)
 
 /* Finds socket connection object by file descriptor */
index 3d859cf70bed9917ddf88d59622cfad9c55b13f1..e4a6a25c7ff260e9e54a54bb5fbafef9989de41c 100644 (file)
@@ -76,8 +76,8 @@ SILC_TASK_CALLBACK(silc_client_key_agreement_close)
 {
   SilcClientKeyAgreement ke = (SilcClientKeyAgreement)context;
 
-  silc_schedule_unset_listen_fd(ke->sock->sock);
-  silc_schedule_unset_listen_fd(ke->fd);
+  silc_schedule_unset_listen_fd(ke->client->schedule, ke->sock->sock);
+  silc_schedule_unset_listen_fd(ke->client->schedule, ke->fd);
   silc_net_close_connection(ke->sock->sock);
   silc_net_close_connection(ke->fd);
   silc_socket_free(ke->sock);
@@ -120,7 +120,7 @@ SILC_TASK_CALLBACK(silc_client_key_agreement_final)
   if (ctx->dest_id)
     silc_free(ctx->dest_id);
   silc_task_unregister_by_fd(client->io_queue, ke->fd);
-  silc_schedule_unset_listen_fd(ke->fd);
+  silc_schedule_unset_listen_fd(ke->client->schedule, ke->fd);
   silc_net_close_connection(ke->fd);
   if (ke->timeout)
     silc_task_unregister(client->timeout_queue, ke->timeout);
@@ -158,7 +158,7 @@ SILC_TASK_CALLBACK(silc_client_process_key_agreement)
     ke->completion(ke->client, ke->conn, ke->client_entry, 
                   SILC_KEY_AGREEMENT_ERROR, NULL, ke->context);
     silc_task_unregister_by_fd(client->io_queue, ke->fd);
-    silc_schedule_unset_listen_fd(ke->fd);
+    silc_schedule_unset_listen_fd(ke->client->schedule, ke->fd);
     silc_net_close_connection(ke->fd);
     if (ke->timeout)
       silc_task_unregister(client->timeout_queue, ke->timeout);
@@ -185,7 +185,7 @@ SILC_TASK_CALLBACK(silc_client_process_key_agreement)
     ke->completion(ke->client, ke->conn, ke->client_entry, 
                   SILC_KEY_AGREEMENT_ERROR, NULL, ke->context);
     silc_task_unregister_by_fd(client->io_queue, ke->fd);
-    silc_schedule_unset_listen_fd(ke->fd);
+    silc_schedule_unset_listen_fd(ke->client->schedule, ke->fd);
     silc_net_close_connection(ke->fd);
     if (ke->timeout)
       silc_task_unregister(client->timeout_queue, ke->timeout);
@@ -245,7 +245,7 @@ SILC_TASK_CALLBACK(silc_client_key_agreement_timeout)
   ke->client_entry->ke = NULL;
   if (ke->fd)
     silc_task_unregister_by_fd(ke->client->io_queue, ke->fd);
-  silc_schedule_unset_listen_fd(ke->fd);
+  silc_schedule_unset_listen_fd(ke->client->schedule, ke->fd);
   silc_net_close_connection(ke->fd);
   silc_free(ke);
 }
@@ -370,7 +370,7 @@ silc_client_connect_to_client_internal(SilcClientInternalConnectContext *ctx)
                                 SILC_TASK_FD,
                                 SILC_TASK_PRI_NORMAL);
   silc_task_reset_iotype(ctx->task, SILC_TASK_WRITE);
-  silc_schedule_set_listen_fd(sock, ctx->task->iomask);
+  silc_schedule_set_listen_fd(ctx->client->schedule, sock, ctx->task->iomask);
 
   ctx->sock = sock;
 
@@ -427,7 +427,7 @@ SILC_TASK_CALLBACK(silc_client_perform_key_agreement_start)
                       ctx->port, ctx->host);
 
       /* Unregister old connection try */
-      silc_schedule_unset_listen_fd(fd);
+      silc_schedule_unset_listen_fd(client->schedule, fd);
       silc_net_close_connection(fd);
       silc_task_unregister(client->io_queue, ctx->task);
 
@@ -438,7 +438,7 @@ SILC_TASK_CALLBACK(silc_client_perform_key_agreement_start)
       /* Connection failed and we won't try anymore */
       client->ops->say(client, conn, "Could not connect to client %s: %s",
                       ctx->host, strerror(opt));
-      silc_schedule_unset_listen_fd(fd);
+      silc_schedule_unset_listen_fd(client->schedule, fd);
       silc_net_close_connection(fd);
       silc_task_unregister(client->io_queue, ctx->task);
       silc_free(ctx->host);
@@ -452,7 +452,7 @@ SILC_TASK_CALLBACK(silc_client_perform_key_agreement_start)
     return;
   }
 
-  silc_schedule_unset_listen_fd(fd);
+  silc_schedule_unset_listen_fd(client->schedule, fd);
   silc_task_unregister(client->io_queue, ctx->task);
 
   ke->fd = fd;
index c1ab6595e4efe8cfda4282b29fcb0149f5c4f5fd..7064629ff2d2cbebcf670b043c9ddb20087fc327 100644 (file)
@@ -2,9 +2,9 @@
 
   silccommand.c
 
-  Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
+  Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 1997 - 2000 Pekka Riikonen
+  Copyright (C) 1997 - 2001 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
index 32ef4ba59dfaee6a5262690ef664598811a0a21c..eeda5a8cdd368a492e9b95918c933b65ecbcbee2 100644 (file)
@@ -6,9 +6,9 @@
  *
  * COPYRIGHT
  *
- * Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
+ * Author: Pekka Riikonen <priikone@silcnet.org>
  *
- * Copyright (C) 1997 - 2000 Pekka Riikonen
+ * Copyright (C) 1997 - 2001 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
index 79ac3e4f3ff318176ce15fa64c27e2897d920c5f..9d7f7e9d3e8dc4da33a12568521eae84751a09c5 100644 (file)
 
 AUTOMAKE_OPTIONS = 1.0 no-dependencies foreign
 
+if SILC_WIN32
+SUBDIRS=win32
+else
+SUBDIRS=unix
+endif
+
 noinst_LIBRARIES = libsilcutil.a
 
 libsilcutil_a_SOURCES = \
@@ -26,7 +32,6 @@ libsilcutil_a_SOURCES = \
        silclog.c \
        silcmemory.c \
        silcnet.c \
-       silcschedule.c \
        silctask.c \
        silcutil.c \
        silchashtable.c
index a55974690001b0ce85d29e93f6c9dd9bcd929c4c..def68e1c7f379a29d808aa21412a6d19d7cfe9b7 100644 (file)
-/*
-
-  silcschedule.h
-
-  Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
-
-  Copyright (C) 1998 - 2000 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; either version 2 of the License, or
-  (at your option) any later version.
-  
-  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.
-
-*/
+/****h* silcutil/silcschedule.h
+ *
+ * NAME
+ *
+ * silcschedule.h
+ *
+ * COPYRIGHT
+ *
+ * Author: Pekka Riikonen <priikone@silcnet.org>
+ *
+ * Copyright (C) 1998 - 2001 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ *
+ */
 
 #ifndef SILCSCHEDULE_H
 #define SILCSCHEDULE_H
 
-/* Structure holding list of file descriptors, scheduler is supposed to
-   be listenning. The max_fd field is the maximum number of possible file
-   descriptors in the list. This value is set at the initialization
-   of the scheduler and it usually is the maximum number of connections 
-   allowed. */
-typedef struct {
-  int *fd;
-  uint32 last_fd;
-  uint32 max_fd;
-} SilcScheduleFdList;
-
-/* 
-   Silc Schedule object. 
-
-   This is the actual schedule object in Silc. Both Silc client and server 
-   uses this same scheduler. Actually, this scheduler could be used by any
-   program needing scheduling.
-
-   Following short description of the fields:
-
-   SilcTaskQueue fd_queue
-
-       Task queue hook for non-timeout tasks. Usually this means that these
-       tasks perform different kind of I/O on file descriptors. File 
-       descriptors are usually network sockets but they actually can be
-       any file descriptors. This hook is initialized in silc_schedule_init
-       function. Timeout tasks should not be added to this queue because
-       they will never expire.
-
-   SilcTaskQueue timeout_queue
-
-       Task queue hook for timeout tasks. This hook is reserved specificly
-       for tasks with timeout. Non-timeout tasks should not be added to this
-       queue because they will never get scheduled. This hook is also
-       initialized in silc_schedule_init function.
-
-   SilcTaskQueue generic_queue
-
-       Task queue hook for generic tasks. This hook is reserved specificly
-       for generic tasks, tasks that apply to all file descriptors, except
-       to those that have specificly registered a non-timeout task. This hook
-       is also initialized in silc_schedule_init function.
-
-   SilcScheduleFdList fd_list
-
-       List of file descriptors the scheduler is supposed to be listenning.
-       This is updated internally.
-
-   struct timeval *timeout;
-
-       Pointer to the schedules next timeout. Value of this timeout is
-       automatically updated in the silc_schedule function.
-
-   int valid
-
-       Marks validity of the scheduler. This is a boolean value. When this
-       is false the scheduler is terminated and the program will end. This
-       set to true when the scheduler is initialized with silc_schedule_init
-       function.
-
-   fd_set in
-   fd_set out
-
-       File descriptor sets for select(). These are automatically managed
-       by the scheduler and should not be touched otherwise.
-
-   int max_fd
-
-       Number of maximum file descriptors for select(). This, as well, is
-       managed automatically by the scheduler and should be considered to 
-       be read-only field otherwise.
-
-*/
-
-typedef struct {
-  SilcTaskQueue fd_queue;
-  SilcTaskQueue timeout_queue;
-  SilcTaskQueue generic_queue;
-  SilcScheduleFdList fd_list;
-  struct timeval *timeout;
-  int valid;
-  fd_set in;
-  fd_set out;
-  int max_fd;
-} SilcScheduleObject;
-
-typedef SilcScheduleObject SilcSchedule;
+/****s* silcutil/SilcScheduleAPI/SilcSchedule
+ *
+ * NAME
+ * 
+ *    typedef struct SilcScheduleStruct *SilcSchedule;
+ *
+ * DESCRIPTION
+ *
+ *    This context is the actual Scheduler and is allocated by
+ *    the silc_schedule_init funtion.  The context is given as argument
+ *    to all silc_schedule_* functions.  It must be freed by the 
+ *    silc_schedule_uninit function.
+ *
+ ***/
+typedef struct SilcScheduleStruct *SilcSchedule;
 
 /* Prototypes */
-void silc_schedule_init(SilcTaskQueue *fd_queue,
-                       SilcTaskQueue *timeout_queue,
-                       SilcTaskQueue *generic_queue,
-                       int max_fd);
-int silc_schedule_uninit();
-void silc_schedule_stop();
-void silc_schedule_set_listen_fd(int fd, uint32 iomask);
-void silc_schedule_unset_listen_fd(int fd);
-void silc_schedule();
-int silc_schedule_one(int block);
+
+/****f* silcutil/SilcScheduleAPI/silc_schedule_init
+ *
+ * SYNOPSIS
+ *
+ *    SilcSchedule silc_schedule_init(SilcTaskQueue *fd_queue,
+ *                                    SilcTaskQueue *timeout_queue,
+ *                                    SilcTaskQueue *generic_queue,
+ *                                    int max_fd);
+ *
+ * DESCRIPTION
+ *
+ *    Initializes the scheduler. Sets the non-timeout task queue hook and
+ *    the timeout task queue hook. This must be called before the scheduler
+ *    is able to work. This will allocate the queue pointers if they are
+ *    not allocated. Returns the scheduler context that must be freed by
+ *    the silc_schedule_uninit function.
+ *
+ ***/
+SilcSchedule silc_schedule_init(SilcTaskQueue *fd_queue,
+                               SilcTaskQueue *timeout_queue,
+                               SilcTaskQueue *generic_queue,
+                               int max_fd);
+
+/****f* silcutil/SilcScheduleAPI/silc_schedule_uninit
+ *
+ * SYNOPSIS
+ *
+ *    bool silc_schedule_uninit(SilcSchedule schedule);
+ *
+ * DESCRIPTION
+ *
+ *    Uninitializes the schedule. This is called when the program is ready
+ *    to end. This removes all tasks and task queues. Returns FALSE if the
+ *    scheduler could not be uninitialized. This happens when the scheduler
+ *    is still valid and silc_schedule_stop has not been called.
+ *
+ ***/
+bool silc_schedule_uninit(SilcSchedule schedule);
+
+/****f* silcutil/SilcScheduleAPI/silc_schedule_stop
+ *
+ * SYNOPSIS
+ *
+ *    void silc_schedule_stop(SilcSchedule schedule);
+ *
+ * DESCRIPTION
+ *
+ *    Stops the scheduler even if it is not supposed to be stopped yet. 
+ *    After calling this, one must call silc_schedule_uninit (after the 
+ *    silc_schedule has returned).
+ *
+ ***/
+void silc_schedule_stop(SilcSchedule schedule);
+
+/****f* silcutil/SilcScheduleAPI/silc_schedule_set_listen_fd
+ *
+ * SYNOPSIS
+ *
+ *    void silc_schedule_set_listen_fd(SilcSchedule schedule, 
+ *                                     int fd, uint32 iomask);
+ *
+ * DESCRIPTION
+ *
+ *    Sets a file descriptor to be listened by the scheduler. One can
+ *    call this directly if wanted. This can be called multiple times for
+ *    one file descriptor to set different iomasks.
+ *
+ ***/
+void silc_schedule_set_listen_fd(SilcSchedule schedule, int fd, uint32 iomask);
+
+/****f* silcutil/SilcScheduleAPI/silc_schedule_unset_listen_fd
+ *
+ * SYNOPSIS
+ *
+ *    void silc_schedule_unset_listen_fd(SilcSchedule schedule, int fd);
+ *
+ * DESCRIPTION
+ *
+ *    Removes a file descriptor from listen list.  The file descriptor
+ *    is not listened by the scheduler after this function.
+ *
+ ***/
+void silc_schedule_unset_listen_fd(SilcSchedule schedule, int fd);
+
+/****f* silcutil/SilcScheduleAPI/silc_schedule
+ *
+ * SYNOPSIS
+ *
+ *    void silc_schedule(SilcSchedule schedule);
+ *
+ * DESCRIPTION
+ *
+ *    The SILC scheduler. This is actually the main routine in SILC programs.
+ *    When this returns the program is to be ended. Before this function can
+ *    be called, one must call silc_schedule_init function.
+ *
+ ***/
+void silc_schedule(SilcSchedule schedule);
+
+/****f* silcutil/SilcScheduleAPI/silc_schedule
+ *
+ * SYNOPSIS
+ *
+ *    bool silc_schedule_one(SilcSchedule schedule, int block);
+ *
+ * DESCRIPTION
+ *
+ *    Same as the silc_schedule but runs the scheduler only one round
+ *    and then returns.  This function is handy when the SILC scheduler
+ *    is used inside some other external scheduler, for example.  If
+ *    the `timeout_usecs' is positive a timeout will be added to the
+ *    scheduler.  The function will not return in this timeout unless
+ *    some other event occurs.
+ *
+ ***/
+bool silc_schedule_one(SilcSchedule schedule, int timeout_usecs);
 
 #endif
index 45ecdbff1251b42a798d878ef43475a24194ce34..5697a3ac5986e3dee45c938d796f13a49b6e848f 100644 (file)
@@ -2,9 +2,9 @@
 
   silctask.c
 
-  Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
+  Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 1998 - 2000 Pekka Riikonen
+  Copyright (C) 1998 - 2001 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
    queue becomes valid task queue. If it is FALSE scheduler will skip
    the queue. */
 
-void silc_task_queue_alloc(SilcTaskQueue *new, int valid)
+void silc_task_queue_alloc(SilcSchedule schedule, SilcTaskQueue *new, 
+                          bool valid)
 {
-
   SILC_LOG_DEBUG(("Allocating new task queue"));
 
   *new = silc_calloc(1, sizeof(**new));
 
   /* Set the pointers */
+  (*new)->schedule = schedule;
   (*new)->valid = valid;
-  (*new)->task = NULL;
 }
 
 /* Free's a task queue. */
 
-void silc_task_queue_free(SilcTaskQueue old)
+void silc_task_queue_free(SilcTaskQueue queue)
 {
-  if (old)
-    silc_free(old);
+  silc_free(queue);
 }
 
 /* Adds a non-timeout task into the task queue. This function is used
@@ -284,7 +283,8 @@ SilcTask silc_task_register(SilcTaskQueue queue, int fd,
 
        /* Add the fd to be listened, the task found now applies to this
           fd as well. */
-       silc_schedule_set_listen_fd(fd, (1L << SILC_TASK_READ));
+       silc_schedule_set_listen_fd(queue->schedule, 
+                                   fd, (1L << SILC_TASK_READ));
        return task;
       }
 
@@ -308,7 +308,7 @@ SilcTask silc_task_register(SilcTaskQueue queue, int fd,
   /* If the task is non-timeout task we have to tell the scheduler that we
      would like to have these tasks scheduled at some odd distant future. */
   if (type != SILC_TASK_TIMEOUT)
-    silc_schedule_set_listen_fd(fd, (1L << SILC_TASK_READ));
+    silc_schedule_set_listen_fd(queue->schedule, fd, (1L << SILC_TASK_READ));
 
   /* Create timeout if marked to be timeout task */
   if (((seconds + useconds) > 0) && (type == SILC_TASK_TIMEOUT)) {
index 1c211c8dd152b2dd3f354608dce1ffbf8808e98e..9cd4547ef8f6e0cad30540c4765b488c120f6063 100644 (file)
@@ -2,9 +2,9 @@
 
   silctask.h
 
-  Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
+  Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 1998 - 2000 Pekka Riikonen
+  Copyright (C) 1998 - 2001 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
 #ifndef SILCTASK_H
 #define SILCTASK_H
 
+typedef struct SilcTaskQueueStruct *SilcTaskQueue;
+typedef struct SilcTaskStruct *SilcTask;
+typedef void (*SilcTaskCallback)(void *, int, void *, int);
+
+#include "silcschedule.h"
+
 /* 
    SILC Task object. 
 
@@ -49,7 +55,7 @@
        structure of the task. Last argument is the file descriptor of the
        task.
 
-   int valid
+   bool valid
 
        Marks for validity of the task. Task that is not valid scheduler 
        will skip. This is boolean value.
 
 */
 
-typedef void (*SilcTaskCallback)(void *, int, void *, int);
-
-typedef struct SilcTaskStruct {
+struct SilcTaskStruct {
   int fd;
   struct timeval timeout;
   void *context;
   SilcTaskCallback callback;
-  int valid;
+  bool valid;
   int priority;
   int iomask;
 
   struct SilcTaskStruct *next;
   struct SilcTaskStruct *prev;
-} SilcTaskObject;
-
-typedef SilcTaskObject *SilcTask;
+};
 
 /* 
    SILC Task types.
@@ -166,6 +168,10 @@ typedef enum {
 
    Short description of the field following:
 
+   SilcSchedule schedule
+
+       A back pointer to the scheduler.
+
    SilcTask task
 
        Pointer to the tasks in the queue.
@@ -185,13 +191,12 @@ typedef enum {
 
 */
 
-typedef struct SilcTaskQueueStruct {
+struct SilcTaskQueueStruct {
+  SilcSchedule schedule;
   SilcTask task;
   int valid;
   struct timeval timeout;
-} SilcTaskQueueObject;
-
-typedef SilcTaskQueueObject *SilcTaskQueue;
+};
 
 /* Marks for all tasks in a task queue. This can be passed to 
    unregister_task function to cancel all tasks at once. */
@@ -230,8 +235,9 @@ static void func(void *qptr, int type, void *context, int fd)
 void func(void *qptr, int type, void *context, int fd)
 
 /* Prototypes */
-void silc_task_queue_alloc(SilcTaskQueue *new, int valid);
-void silc_task_queue_free(SilcTaskQueue old);
+void silc_task_queue_alloc(SilcSchedule schedule, SilcTaskQueue *new, 
+                          bool valid);
+void silc_task_queue_free(SilcTaskQueue queue);
 SilcTask silc_task_add(SilcTaskQueue queue, SilcTask new, 
                       SilcTaskPriority priority);
 SilcTask silc_task_add_timeout(SilcTaskQueue queue, SilcTask new,
diff --git a/lib/silcutil/unix/Makefile.am b/lib/silcutil/unix/Makefile.am
new file mode 100644 (file)
index 0000000..3eb7f7d
--- /dev/null
@@ -0,0 +1,28 @@
+#
+#  Makefile.am
+#
+#  Author: Pekka Riikonen <priikone@silcnet.org>
+#
+#  Copyright (C) 2001 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; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  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.
+#
+
+AUTOMAKE_OPTIONS = 1.0 no-dependencies foreign
+
+noinst_LIBRARIES = libsilcunixutil.a
+
+libsilcunixutil_a_SOURCES = \
+       silcunixschedule.c
+
+EXTRA_DIST = *.h
+
+include $(top_srcdir)/Makefile.defines.in
similarity index 63%
rename from lib/silcutil/silcschedule.c
rename to lib/silcutil/unix/silcunixschedule.c
index 5929720daf4ed2c6c770a891a04359996cd9b4ba..03bd312109e4a9a08971dd2b14e556e46ceaf9ea 100644 (file)
@@ -1,10 +1,10 @@
 /*
 
-  silcschedule.c
+  silcunixschedule.c
 
-  Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
+  Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 1998 - 2000 Pekka Riikonen
+  Copyright (C) 1998 - 2001 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
 
 #include "silcincludes.h"
 
-/* The actual schedule object. */
-static SilcSchedule schedule;
+/* Structure holding list of file descriptors, scheduler is supposed to
+   be listenning. The max_fd field is the maximum number of possible file
+   descriptors in the list. This value is set at the initialization
+   of the scheduler and it usually is the maximum number of connections 
+   allowed. */
+typedef struct {
+  int *fd;
+  uint32 last_fd;
+  uint32 max_fd;
+} SilcScheduleFdList;
 
-/* Initializes the schedule. Sets the non-timeout task queue hook and
-   the timeout task queue hook. This must be called before the schedule
-   is able to work. */
+/* 
+   SILC Unix Scheduler structure.
 
-void silc_schedule_init(SilcTaskQueue *fd_queue,
-                       SilcTaskQueue *timeout_queue,
-                       SilcTaskQueue *generic_queue,
-                       int max_fd)
+   This is the actual schedule object in SILC. Both SILC client and server 
+   uses this same scheduler. Actually, this scheduler could be used by any
+   program needing scheduling.
+
+   Following short description of the fields:
+
+   SilcTaskQueue fd_queue
+
+       Task queue hook for non-timeout tasks. Usually this means that these
+       tasks perform different kind of I/O on file descriptors. File 
+       descriptors are usually network sockets but they actually can be
+       any file descriptors. This hook is initialized in silc_schedule_init
+       function. Timeout tasks should not be added to this queue because
+       they will never expire.
+
+   SilcTaskQueue timeout_queue
+
+       Task queue hook for timeout tasks. This hook is reserved specificly
+       for tasks with timeout. Non-timeout tasks should not be added to this
+       queue because they will never get scheduled. This hook is also
+       initialized in silc_schedule_init function.
+
+   SilcTaskQueue generic_queue
+
+       Task queue hook for generic tasks. This hook is reserved specificly
+       for generic tasks, tasks that apply to all file descriptors, except
+       to those that have specificly registered a non-timeout task. This hook
+       is also initialized in silc_schedule_init function.
+
+   SilcScheduleFdList fd_list
+
+       List of file descriptors the scheduler is supposed to be listenning.
+       This is updated internally.
+
+   struct timeval *timeout;
+
+       Pointer to the schedules next timeout. Value of this timeout is
+       automatically updated in the silc_schedule function.
+
+   int valid
+
+       Marks validity of the scheduler. This is a boolean value. When this
+       is false the scheduler is terminated and the program will end. This
+       set to true when the scheduler is initialized with silc_schedule_init
+       function.
+
+   fd_set in
+   fd_set out
+
+       File descriptor sets for select(). These are automatically managed
+       by the scheduler and should not be touched otherwise.
+
+   int max_fd
+
+       Number of maximum file descriptors for select(). This, as well, is
+       managed automatically by the scheduler and should be considered to 
+       be read-only field otherwise.
+
+*/
+struct SilcScheduleStruct {
+  SilcTaskQueue fd_queue;
+  SilcTaskQueue timeout_queue;
+  SilcTaskQueue generic_queue;
+  SilcScheduleFdList fd_list;
+  struct timeval *timeout;
+  int valid;
+  fd_set in;
+  fd_set out;
+  int max_fd;
+};
+
+/* Initializes the scheduler. Sets the non-timeout task queue hook and
+   the timeout task queue hook. This must be called before the scheduler
+   is able to work. This will allocate the queue pointers if they are
+   not allocated. Returns the scheduler context that must be freed by
+   the silc_schedule_uninit function. */
+
+SilcSchedule silc_schedule_init(SilcTaskQueue *fd_queue,
+                               SilcTaskQueue *timeout_queue,
+                               SilcTaskQueue *generic_queue,
+                               int max_fd)
 {
+  SilcSchedule schedule;
   int i;
 
   SILC_LOG_DEBUG(("Initializing scheduler"));
 
+  schedule = silc_calloc(1, sizeof(*schedule));
+
   /* Register the task queues if they are not registered already. In SILC
      we have by default three task queues. One task queue for non-timeout
      tasks which perform different kind of I/O on file descriptors, timeout
      task queue for timeout tasks, and, generic non-timeout task queue whose
      tasks apply to all connections. */
   if (!*fd_queue)
-    silc_task_queue_alloc(fd_queue, TRUE);
+    silc_task_queue_alloc(schedule, fd_queue, TRUE);
   if (!*timeout_queue)
-    silc_task_queue_alloc(timeout_queue, TRUE);
+    silc_task_queue_alloc(schedule, timeout_queue, TRUE);
   if (!*generic_queue)
-    silc_task_queue_alloc(generic_queue, TRUE);
-
-  /* Initialize the schedule */
-  memset(&schedule, 0, sizeof(schedule));
-  schedule.fd_queue = *fd_queue;
-  schedule.timeout_queue = *timeout_queue;
-  schedule.generic_queue = *generic_queue;
-  schedule.fd_list.fd = silc_calloc(max_fd, sizeof(int));
-  schedule.fd_list.last_fd = 0;
-  schedule.fd_list.max_fd = max_fd;
-  schedule.timeout = NULL;
-  schedule.valid = TRUE;
-  FD_ZERO(&schedule.in);
-  FD_ZERO(&schedule.out);
-  schedule.max_fd = -1;
+    silc_task_queue_alloc(schedule, generic_queue, TRUE);
+
+  /* Initialize the scheduler */
+  schedule->fd_queue = *fd_queue;
+  schedule->timeout_queue = *timeout_queue;
+  schedule->generic_queue = *generic_queue;
+  schedule->fd_list.fd = silc_calloc(max_fd, sizeof(int));
+  schedule->fd_list.last_fd = 0;
+  schedule->fd_list.max_fd = max_fd;
+  schedule->timeout = NULL;
+  schedule->valid = TRUE;
+  FD_ZERO(&schedule->in);
+  FD_ZERO(&schedule->out);
+  schedule->max_fd = -1;
   for (i = 0; i < max_fd; i++)
-    schedule.fd_list.fd[i] = -1;
+    schedule->fd_list.fd[i] = -1;
+
+  return schedule;
 }
 
 /* Uninitializes the schedule. This is called when the program is ready
-   to end. This removes all tasks and task queues. */
+   to end. This removes all tasks and task queues. Returns FALSE if the
+   scheduler could not be uninitialized. This happens when the scheduler
+   is still valid and silc_schedule_stop has not been called. */
 
-int silc_schedule_uninit()
+bool silc_schedule_uninit(SilcSchedule schedule)
 {
 
   SILC_LOG_DEBUG(("Uninitializing scheduler"));
 
-  if (schedule.valid == TRUE)
+  if (schedule->valid == TRUE)
     return FALSE;
 
   /* Unregister all tasks */
-  if (schedule.fd_queue)
-    silc_task_remove(schedule.fd_queue, SILC_ALL_TASKS);
-  if (schedule.timeout_queue)
-    silc_task_remove(schedule.timeout_queue, SILC_ALL_TASKS);
-  if (schedule.generic_queue)
-    silc_task_remove(schedule.generic_queue, SILC_ALL_TASKS);
+  if (schedule->fd_queue)
+    silc_task_remove(schedule->fd_queue, SILC_ALL_TASKS);
+  if (schedule->timeout_queue)
+    silc_task_remove(schedule->timeout_queue, SILC_ALL_TASKS);
+  if (schedule->generic_queue)
+    silc_task_remove(schedule->generic_queue, SILC_ALL_TASKS);
 
   /* Unregister all task queues */
-  if (schedule.fd_queue)
-    silc_task_queue_free(schedule.fd_queue);
-  if (schedule.timeout_queue)
-    silc_task_queue_free(schedule.timeout_queue);
-  if (schedule.generic_queue)
-    silc_task_queue_free(schedule.generic_queue);
+  if (schedule->fd_queue)
+    silc_task_queue_free(schedule->fd_queue);
+  if (schedule->timeout_queue)
+    silc_task_queue_free(schedule->timeout_queue);
+  if (schedule->generic_queue)
+    silc_task_queue_free(schedule->generic_queue);
 
   /* Clear the fd list */
-  if (schedule.fd_list.fd) {
-    memset(schedule.fd_list.fd, -1, schedule.fd_list.max_fd);
-    silc_free(schedule.fd_list.fd);
+  if (schedule->fd_list.fd) {
+    memset(schedule->fd_list.fd, -1, schedule->fd_list.max_fd);
+    silc_free(schedule->fd_list.fd);
   }
 
   memset(&schedule, 'F', sizeof(schedule));
@@ -107,46 +197,40 @@ int silc_schedule_uninit()
    After calling this, one should call silc_schedule_uninit (after the 
    silc_schedule has returned). */
 
-void silc_schedule_stop()
+void silc_schedule_stop(SilcSchedule schedule)
 {
   SILC_LOG_DEBUG(("Stopping scheduler"));
 
-  if (schedule.valid == TRUE)
-    schedule.valid = FALSE;
+  if (schedule->valid == TRUE)
+    schedule->valid = FALSE;
 }
 
 /* Sets a file descriptor to be listened by select() in scheduler. One can
    call this directly if wanted. This can be called multiple times for
    one file descriptor to set different iomasks. */
 
-void silc_schedule_set_listen_fd(int fd, uint32 iomask)
+void silc_schedule_set_listen_fd(SilcSchedule schedule, int fd, uint32 iomask)
 {
-  assert(schedule.valid != FALSE);
-  assert(fd < schedule.fd_list.max_fd);
-
-  schedule.fd_list.fd[fd] = iomask;
+  schedule->fd_list.fd[fd] = iomask;
   
-  if (fd > schedule.fd_list.last_fd)
-    schedule.fd_list.last_fd = fd;
+  if (fd > schedule->fd_list.last_fd)
+    schedule->fd_list.last_fd = fd;
 }
 
 /* Removes a file descriptor from listen list. */
 
-void silc_schedule_unset_listen_fd(int fd)
+void silc_schedule_unset_listen_fd(SilcSchedule schedule, int fd)
 {
-  assert(schedule.valid != FALSE);
-  assert(fd < schedule.fd_list.max_fd);
-
-  schedule.fd_list.fd[fd] = -1;
+  schedule->fd_list.fd[fd] = -1;
   
-  if (fd == schedule.fd_list.last_fd) {
+  if (fd == schedule->fd_list.last_fd) {
     int i;
 
     for (i = fd; i >= 0; i--)
-      if (schedule.fd_list.fd[i] != -1)
+      if (schedule->fd_list.fd[i] != -1)
        break;
 
-    schedule.fd_list.last_fd = i < 0 ? 0 : i;
+    schedule->fd_list.last_fd = i < 0 ? 0 : i;
   }
 }
 
@@ -158,7 +242,7 @@ void silc_schedule_unset_listen_fd(int fd)
 
 #define SILC_SCHEDULE_RUN_TASKS                                                   \
 do {                                                                      \
-  queue = schedule.fd_queue;                                              \
+  queue = schedule->fd_queue;                                             \
   if (queue && queue->valid == TRUE && queue->task) {                     \
     task = queue->task;                                                           \
                                                                           \
@@ -172,7 +256,7 @@ do {                                                                           \
                                                                           \
       if (task->valid) {                                                  \
        /* Task ready for reading */                                       \
-       if ((FD_ISSET(task->fd, &schedule.in)) &&                          \
+       if ((FD_ISSET(task->fd, &schedule->in)) &&                         \
            (task->iomask & (1L << SILC_TASK_READ))) {                     \
          task->callback(queue, SILC_TASK_READ, task->context, task->fd);  \
           is_run = TRUE;                                                  \
@@ -181,7 +265,7 @@ do {                                                                           \
                                                                           \
       if (task->valid) {                                                  \
        /* Task ready for writing */                                       \
-       if ((FD_ISSET(task->fd, &schedule.out)) &&                         \
+       if ((FD_ISSET(task->fd, &schedule->out)) &&                        \
            (task->iomask & (1L << SILC_TASK_WRITE))) {                    \
          task->callback(queue, SILC_TASK_WRITE, task->context, task->fd); \
           is_run = TRUE;                                                  \
@@ -216,20 +300,20 @@ do {                                                                         \
 
 #define SILC_SCHEDULE_SELECT_TASKS                             \
 do {                                                           \
-  for (i = 0; i <= schedule.fd_list.last_fd; i++) {            \
-    if (schedule.fd_list.fd[i] != -1) {                                \
+  for (i = 0; i <= schedule->fd_list.last_fd; i++) {           \
+    if (schedule->fd_list.fd[i] != -1) {                               \
                                                                \
       /* Set the max fd value for select() to listen */                \
-      if (i > schedule.max_fd)                                 \
-       schedule.max_fd = i;                                    \
+      if (i > schedule->max_fd)                                        \
+       schedule->max_fd = i;                                   \
                                                                \
       /* Add tasks for reading */                              \
-      if ((schedule.fd_list.fd[i] & (1L << SILC_TASK_READ)))   \
-       FD_SET(i, &schedule.in);                                \
+      if ((schedule->fd_list.fd[i] & (1L << SILC_TASK_READ)))  \
+       FD_SET(i, &schedule->in);                               \
                                                                \
       /* Add tasks for writing */                              \
-      if ((schedule.fd_list.fd[i] & (1L << SILC_TASK_WRITE)))  \
-       FD_SET(i, &schedule.out);                               \
+      if ((schedule->fd_list.fd[i] & (1L << SILC_TASK_WRITE))) \
+       FD_SET(i, &schedule->out);                              \
     }                                                          \
   }                                                             \
 } while(0)
@@ -243,7 +327,7 @@ do {                                                                \
 
 #define SILC_SCHEDULE_RUN_TIMEOUT_TASKS                                        \
 do {                                                                   \
-  queue = schedule.timeout_queue;                                      \
+  queue = schedule->timeout_queue;                                     \
   if (queue && queue->valid == TRUE && queue->task) {                  \
     task = queue->task;                                                        \
                                                                        \
@@ -298,13 +382,13 @@ do {                                                                      \
 
 #define SILC_SCHEDULE_SELECT_TIMEOUT                                       \
 do {                                                                       \
-  if (schedule.timeout_queue && schedule.timeout_queue->valid == TRUE) {    \
-    queue = schedule.timeout_queue;                                        \
+  if (schedule->timeout_queue && schedule->timeout_queue->valid == TRUE) {    \
+    queue = schedule->timeout_queue;                                       \
     task = NULL;                                                           \
                                                                            \
     /* Get the current time */                                             \
     gettimeofday(&curtime, NULL);                                          \
-    schedule.timeout = NULL;                                               \
+    schedule->timeout = NULL;                                              \
                                                                            \
     /* First task in the task queue has always the smallest timeout. */            \
     task = queue->task;                                                            \
@@ -318,7 +402,7 @@ do {                                                                            \
                                                                            \
          /* The task(s) has expired and doesn't exist on the task queue    \
             anymore. We continue with new timeout. */                      \
-          queue = schedule.timeout_queue;                                  \
+          queue = schedule->timeout_queue;                                 \
           task = queue->task;                                              \
           if (task == NULL || task->valid == FALSE)                        \
             break;                                                         \
@@ -351,7 +435,7 @@ do {                                                                            \
     }                                                                      \
     /* Save the timeout */                                                 \
     if (task)                                                              \
-      schedule.timeout = &queue->timeout;                                  \
+      schedule->timeout = &queue->timeout;                                 \
   }                                                                        \
 } while(0)
 
@@ -364,16 +448,16 @@ do {                                                                          \
 do {                                                                        \
   if (is_run == FALSE) {                                                    \
     SILC_LOG_DEBUG(("Running generic tasks"));                              \
-    for (i = 0; i <= schedule.fd_list.last_fd; i++)                         \
-      if (schedule.fd_list.fd[i] != -1) {                                   \
+    for (i = 0; i <= schedule->fd_list.last_fd; i++)                        \
+      if (schedule->fd_list.fd[i] != -1) {                                  \
                                                                             \
        /* Check whether this fd is select()ed. */                           \
-       if ((FD_ISSET(i, &schedule.in)) || (FD_ISSET(i, &schedule.out))) {   \
+       if ((FD_ISSET(i, &schedule->in)) || (FD_ISSET(i, &schedule->out))) {   \
                                                                             \
          /* It was selected. Now find the tasks from task queue and execute \
             all generic tasks. */                                           \
-         if (schedule.generic_queue && schedule.generic_queue->valid) {     \
-           queue = schedule.generic_queue;                                  \
+         if (schedule->generic_queue && schedule->generic_queue->valid) {     \
+           queue = schedule->generic_queue;                                 \
                                                                             \
            if (!queue->task)                                                \
              break;                                                         \
@@ -385,16 +469,16 @@ do {                                                                           \
                 execution beacuse the task might have been unregistered     \
                 in the callback function, ie. it is not valid anymore. */   \
                                                                             \
-             if (task->valid && schedule.fd_list.fd[i] != -1) {             \
+             if (task->valid && schedule->fd_list.fd[i] != -1) {            \
                /* Task ready for reading */                                 \
-               if ((schedule.fd_list.fd[i] & (1L << SILC_TASK_READ)))       \
+               if ((schedule->fd_list.fd[i] & (1L << SILC_TASK_READ)))      \
                  task->callback(queue, SILC_TASK_READ,                      \
                                 task->context, i);                          \
              }                                                              \
                                                                             \
-             if (task->valid && schedule.fd_list.fd[i] != -1) {             \
+             if (task->valid && schedule->fd_list.fd[i] != -1) {            \
                /* Task ready for writing */                                 \
-               if ((schedule.fd_list.fd[i] & (1L << SILC_TASK_WRITE)))      \
+               if ((schedule->fd_list.fd[i] & (1L << SILC_TASK_WRITE)))             \
                  task->callback(queue, SILC_TASK_WRITE,                     \
                                 task->context, i);                          \
              }                                                              \
@@ -424,7 +508,7 @@ do {                                                                             \
   }                                                                         \
 } while(0)
 
-int silc_schedule_one(int timeout_usecs)
+bool silc_schedule_one(SilcSchedule schedule, int timeout_usecs)
 {
   struct timeval timeout;
   int is_run, i;
@@ -436,16 +520,16 @@ int silc_schedule_one(int timeout_usecs)
 
   /* If the task queues aren't initialized or we aren't valid anymore
      we will return */
-  if ((!schedule.fd_queue && !schedule.timeout_queue 
-       && !schedule.generic_queue) || schedule.valid == FALSE) {
+  if ((!schedule->fd_queue && !schedule->timeout_queue 
+       && !schedule->generic_queue) || schedule->valid == FALSE) {
     SILC_LOG_DEBUG(("Scheduler not valid anymore, exiting"));
     return FALSE;
   }
 
   /* Clear everything */
-  FD_ZERO(&schedule.in);
-  FD_ZERO(&schedule.out);
-  schedule.max_fd = -1;
+  FD_ZERO(&schedule->in);
+  FD_ZERO(&schedule->out);
+  schedule->max_fd = -1;
   is_run = FALSE;
 
   /* Calculate next timeout for select(). This is the timeout value
@@ -456,36 +540,30 @@ int silc_schedule_one(int timeout_usecs)
      tasks. The select() listens to these file descriptors. */
   SILC_SCHEDULE_SELECT_TASKS;
 
-  if (schedule.max_fd == -1 && !schedule.timeout)
+  if (schedule->max_fd == -1 && !schedule->timeout)
     return FALSE;
 
-  if (schedule.timeout) {
-    SILC_LOG_DEBUG(("timeout: sec=%d, usec=%d", schedule.timeout->tv_sec,
-                   schedule.timeout->tv_usec));
+  if (schedule->timeout) {
+    SILC_LOG_DEBUG(("timeout: sec=%d, usec=%d", schedule->timeout->tv_sec,
+                   schedule->timeout->tv_usec));
   }
 
   if (timeout_usecs >= 0) {
     timeout.tv_sec = 0;
     timeout.tv_usec = timeout_usecs;
-    schedule.timeout = &timeout;
+    schedule->timeout = &timeout;
   }
 
   /* This is the main select(). The program blocks here until some
      of the selected file descriptors change status or the selected
      timeout expires. */
   SILC_LOG_DEBUG(("Select"));
-  switch (select(schedule.max_fd + 1, &schedule.in,
-                &schedule.out, 0, schedule.timeout)) {
+  switch (select(schedule->max_fd + 1, &schedule->in,
+                &schedule->out, 0, schedule->timeout)) {
   case -1:
     /* Error */
     if (errno == EINTR)
       break;
-#if 1
-    if (errno == EINVAL && schedule.timeout) {
-      SILC_LOG_ERROR(("Invalid argument (invalid timeout): %lu %lu",
-                     schedule.timeout->tv_sec, schedule.timeout->tv_usec));
-    }
-#endif
     SILC_LOG_ERROR(("Error in select(): %s", strerror(errno)));
     break;
   case 0:
@@ -502,6 +580,7 @@ int silc_schedule_one(int timeout_usecs)
     SILC_SCHEDULE_RUN_GENERIC_TASKS;
     break;
   }
+
   return TRUE;
 }
 
@@ -509,16 +588,16 @@ int silc_schedule_one(int timeout_usecs)
    When this returns the program is to be ended. Before this function can
    be called, one must call silc_schedule_init function. */
 
-void silc_schedule()
+void silc_schedule(SilcSchedule schedule)
 {
   SILC_LOG_DEBUG(("Running scheduler"));
 
-  if (schedule.valid == FALSE) {
+  if (schedule->valid == FALSE) {
     SILC_LOG_ERROR(("Scheduler is not valid, stopping"));
     return;
   }
 
   /* Start the scheduler loop */
-  while (silc_schedule_one(-1)) 
+  while (silc_schedule_one(schedule, -1)) 
     ;
 }
diff --git a/lib/silcutil/win32/Makefile.am b/lib/silcutil/win32/Makefile.am
new file mode 100644 (file)
index 0000000..e66c847
--- /dev/null
@@ -0,0 +1,27 @@
+#
+#  Makefile.am
+#
+#  Author: Pekka Riikonen <priikone@silcnet.org>
+#
+#  Copyright (C) 2001 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; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  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.
+#
+
+AUTOMAKE_OPTIONS = 1.0 no-dependencies foreign
+
+noinst_LIBRARIES = libsilcwin32util.a
+
+libsilcwin32util_a_SOURCES = 
+
+EXTRA_DIST = *.h
+
+include $(top_srcdir)/Makefile.defines.in