From 0d88839b0027590e041b90fb0a6611f8c85779ba Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Sat, 23 Jun 2001 13:20:39 +0000 Subject: [PATCH] updates. --- CHANGES | 14 + acconfig.h.pre | 4 + apps/irssi/src/silc/core/silc-core.c | 2 +- apps/silcd/packet_send.c | 2 +- apps/silcd/server.c | 47 +-- apps/silcd/server_internal.h | 20 +- configure.in.pre | 51 +-- distributions | 11 +- includes/silcincludes.h | 32 +- lib/silcclient/client.c | 27 +- lib/silcclient/client.h | 19 +- lib/silcclient/client_keyagr.c | 20 +- lib/silccore/silccommand.c | 4 +- lib/silccore/silccommand.h | 4 +- lib/silcutil/Makefile.am | 7 +- lib/silcutil/silcschedule.h | 271 +++++++++------- lib/silcutil/silctask.c | 20 +- lib/silcutil/silctask.h | 38 ++- lib/silcutil/unix/Makefile.am | 28 ++ .../silcunixschedule.c} | 307 +++++++++++------- lib/silcutil/win32/Makefile.am | 27 ++ 21 files changed, 580 insertions(+), 375 deletions(-) create mode 100644 lib/silcutil/unix/Makefile.am rename lib/silcutil/{silcschedule.c => unix/silcunixschedule.c} (63%) create mode 100644 lib/silcutil/win32/Makefile.am diff --git a/CHANGES b/CHANGES index fe89869c..aa885ab0 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,17 @@ +Sat Jun 23 16:01:00 EEST 2001 Pekka Riikonen + + * 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 * Do not handle JOIN notify in the server if the target client diff --git a/acconfig.h.pre b/acconfig.h.pre index 340d8308..ce215431 100644 --- a/acconfig.h.pre +++ b/acconfig.h.pre @@ -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) */ diff --git a/apps/irssi/src/silc/core/silc-core.c b/apps/irssi/src/silc/core/silc-core.c index 787290cc..0c80e52a 100644 --- a/apps/irssi/src/silc/core/silc-core.c +++ b/apps/irssi/src/silc/core/silc-core.c @@ -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; } diff --git a/apps/silcd/packet_send.c b/apps/silcd/packet_send.c index 46a77f18..81cdce52 100644 --- a/apps/silcd/packet_send.c +++ b/apps/silcd/packet_send.c @@ -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 diff --git a/apps/silcd/server.c b/apps/silcd/server.c index ef90e6dc..4dde2b36 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -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); } diff --git a/apps/silcd/server_internal.h b/apps/silcd/server_internal.h index 1de43890..24942e37 100644 --- a/apps/silcd/server_internal.h +++ b/apps/silcd/server_internal.h @@ -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 */ diff --git a/configure.in.pre b/configure.in.pre index 082a6173..293fa1e9 100644 --- a/configure.in.pre +++ b/configure.in.pre @@ -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) diff --git a/distributions b/distributions index 35552d7e..382a7c43 100644 --- a/distributions +++ b/distributions @@ -46,19 +46,28 @@ # 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 diff --git a/includes/silcincludes.h b/includes/silcincludes.h index bf9b2862..f99e5e09 100644 --- a/includes/silcincludes.h +++ b/includes/silcincludes.h @@ -29,29 +29,21 @@ /* Automatically generated configuration header */ #include "silcdefs.h" +#ifdef SILC_WIN32 +#include +#endif + #include #include #include #include #include -#include -#include - #include #include #include #include -#include #include -#ifdef SOCKS5 -#include "socks.h" -#endif - -#ifdef HAVE_GETOPT_H -#include -#endif - #ifdef HAVE_SIGNAL_H #include #else @@ -76,6 +68,20 @@ #error assert.h not found in the system #endif +#ifndef SILC_WIN32 + +#include +#include +#include + +#ifdef HAVE_GETOPT_H +#include +#endif + +#ifdef SOCKS5 +#include "socks.h" +#endif + #include #ifdef HAVE_NETINET_IN_H #include @@ -109,6 +115,8 @@ #include #endif +#endif /* !SILC_WIN32 */ + #ifndef HAVE_GETOPT_LONG #include "../lib/contrib/getopt.h" #endif diff --git a/lib/silcclient/client.c b/lib/silcclient/client.c index 36c4c93d..dde26d53 100644 --- a/lib/silcclient/client.c +++ b/lib/silcclient/client.c @@ -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); diff --git a/lib/silcclient/client.h b/lib/silcclient/client.h index fff7d017..dd27a146 100644 --- a/lib/silcclient/client.h +++ b/lib/silcclient/client.h @@ -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 */ diff --git a/lib/silcclient/client_keyagr.c b/lib/silcclient/client_keyagr.c index 3d859cf7..e4a6a25c 100644 --- a/lib/silcclient/client_keyagr.c +++ b/lib/silcclient/client_keyagr.c @@ -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; diff --git a/lib/silccore/silccommand.c b/lib/silccore/silccommand.c index c1ab6595..7064629f 100644 --- a/lib/silccore/silccommand.c +++ b/lib/silccore/silccommand.c @@ -2,9 +2,9 @@ silccommand.c - Author: Pekka Riikonen + Author: Pekka Riikonen - 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 diff --git a/lib/silccore/silccommand.h b/lib/silccore/silccommand.h index 32ef4ba5..eeda5a8c 100644 --- a/lib/silccore/silccommand.h +++ b/lib/silccore/silccommand.h @@ -6,9 +6,9 @@ * * COPYRIGHT * - * Author: Pekka Riikonen + * Author: Pekka Riikonen * - * 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 diff --git a/lib/silcutil/Makefile.am b/lib/silcutil/Makefile.am index 79ac3e4f..9d7f7e9d 100644 --- a/lib/silcutil/Makefile.am +++ b/lib/silcutil/Makefile.am @@ -18,6 +18,12 @@ 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 diff --git a/lib/silcutil/silcschedule.h b/lib/silcutil/silcschedule.h index a5597469..def68e1c 100644 --- a/lib/silcutil/silcschedule.h +++ b/lib/silcutil/silcschedule.h @@ -1,124 +1,163 @@ -/* - - silcschedule.h - - Author: Pekka Riikonen - - 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 + * + * 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 diff --git a/lib/silcutil/silctask.c b/lib/silcutil/silctask.c index 45ecdbff..5697a3ac 100644 --- a/lib/silcutil/silctask.c +++ b/lib/silcutil/silctask.c @@ -2,9 +2,9 @@ silctask.c - Author: Pekka Riikonen + Author: Pekka Riikonen - 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 @@ -25,24 +25,23 @@ 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)) { diff --git a/lib/silcutil/silctask.h b/lib/silcutil/silctask.h index 1c211c8d..9cd4547e 100644 --- a/lib/silcutil/silctask.h +++ b/lib/silcutil/silctask.h @@ -2,9 +2,9 @@ silctask.h - Author: Pekka Riikonen + Author: Pekka Riikonen - 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 @@ -21,6 +21,12 @@ #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. @@ -81,22 +87,18 @@ */ -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 index 00000000..3eb7f7d2 --- /dev/null +++ b/lib/silcutil/unix/Makefile.am @@ -0,0 +1,28 @@ +# +# Makefile.am +# +# Author: Pekka Riikonen +# +# 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 diff --git a/lib/silcutil/silcschedule.c b/lib/silcutil/unix/silcunixschedule.c similarity index 63% rename from lib/silcutil/silcschedule.c rename to lib/silcutil/unix/silcunixschedule.c index 5929720d..03bd3121 100644 --- a/lib/silcutil/silcschedule.c +++ b/lib/silcutil/unix/silcunixschedule.c @@ -1,10 +1,10 @@ /* - silcschedule.c + silcunixschedule.c - Author: Pekka Riikonen + Author: Pekka Riikonen - 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 @@ -21,82 +21,172 @@ #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 index 00000000..e66c847b --- /dev/null +++ b/lib/silcutil/win32/Makefile.am @@ -0,0 +1,27 @@ +# +# Makefile.am +# +# Author: Pekka Riikonen +# +# 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 -- 2.24.0