From: Pekka Riikonen Date: Sat, 7 Jul 2001 21:58:51 +0000 (+0000) Subject: updates. X-Git-Tag: robodoc-323~100 X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=commitdiff_plain;h=2971471c6955c1217921700290624d4cb3ed303e updates. --- diff --git a/CHANGES b/CHANGES index 15cf29f1..4e515e65 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,11 @@ +Sun Jul 8 00:18:15 EEST 2001 Pekka Riikonen + + * Defined SILC Mutex API and SILC Thread API and implemented + them for Unix. Affected files are + lib/silcutil/silcmutex.h, lib/silcutil/silcthread.h, + lib/silcutil/unix/silcunixmutex.c and + lib/silcutil/unix/silcunixthread.c. + Sat Jul 7 14:40:31 EEST 2001 Pekka Riikonen * Fixed the silc_server_remove_clients_by_server's channel diff --git a/TODO b/TODO index 08a77285..b5a01159 100644 --- a/TODO +++ b/TODO @@ -91,6 +91,8 @@ TODO/bugs In SILC Server TODO/bugs In SILC Libraries =========================== + o Complete the SILC Mutex API and SILC Thread API. + o Incomplete IPv6 support: o All network routines in lib/silcutil/silcnet.[ch] does not @@ -132,18 +134,6 @@ TODO In SILC Protocol TODO After 1.0 ============== - o Pthreads support. A lot of problems are solved with server (and with - client as well) if we add pthread support. We can forget things such - as non-blocking connecting etc, and we can do things such as DNS/IP - lookups async. The server itself also benefits great deal from - threads, especially from performance point of view. - - But, this is not a small task and almost entire SILC Library has to - be made re-entrant. Own API is probably added for the threads support - to make changes in the future as painless as possible. So the API - would have things like silc_mutex_lock, silc_mutex_unlock and - friends... - o X.509 certificate support. SILC protocol supports certificates and it would be great to have support for them. This is a big task as support has to be made for ASN.1 as well. I've looked into OpenSSL diff --git a/acconfig.h.pre b/acconfig.h.pre index ce215431..2e40f0c7 100644 --- a/acconfig.h.pre +++ b/acconfig.h.pre @@ -10,6 +10,9 @@ /* Default configuration file */ #undef SILC_SERVER_CONFIG_FILE +/* Multi-thread support */ +#undef SILC_THREADS + /* Default paths */ #undef SILC_ETCDIR #undef SILC_HELPDIR diff --git a/configure.in.pre b/configure.in.pre index 80b8dec8..23e6da76 100644 --- a/configure.in.pre +++ b/configure.in.pre @@ -67,6 +67,7 @@ AC_CHECK_HEADERS(netinet/in.h netinet/tcp.h netdb.h) AC_CHECK_HEADERS(pwd.h grp.h termcap.h paths.h) AC_CHECK_HEADERS(ncurses.h signal.h ctype.h regex.h) AC_CHECK_HEADERS(arpa/inet.h sys/mman.h limits.h) +AC_CHECK_HEADERS(pthread.h) # Data type checking AC_TYPE_SIGNAL @@ -291,6 +292,7 @@ AC_CHECK_FUNCS(mlock munlock) AC_CHECK_FUNCS(chmod stat fstat getenv putenv strerror ctime gettimeofday) AC_CHECK_FUNCS(getpid getgid getsid getpgid getpgrp getuid) AC_CHECK_FUNCS(strchr strstr strcpy strncpy memcpy memset memmove) +AC_CHECK_FUNCS(pthread_create) # SIM support checking # XXX These needs to be changed as more supported platforms appear. @@ -555,6 +557,28 @@ AC_ARG_ENABLE(debug, esac ], CFLAGS="-O2 -g $CFLAGS" AC_MSG_RESULT(no)) +# Pthread checking +AC_ARG_ENABLE(threads, +[ --disable-threads Do not compile with multi-thread support], +[ case "${enableval}" in + yes) + AC_DEFINE(SILC_THREADS) + AM_CONDITIONAL(SILC_THREADS) + want_threads=true + ;; + *) + want_threads=false + ;; +esac ], AC_DEFINE(SILC_THREADS) + AM_CONDITIONAL(SILC_THREADS) + want_threads=true) + +if test x$want_threads = xtrue; then + AC_TRY_COMPILE([#include ], + [pthread_attr_t attr; pthread_attr_init(&attr);], + LIBS="$LIBS -lpthread") +fi + # # Other configure scripts # diff --git a/includes/silcincludes.h b/includes/silcincludes.h index 1c4ef761..6ffb7186 100644 --- a/includes/silcincludes.h +++ b/includes/silcincludes.h @@ -130,6 +130,10 @@ #include #endif +#ifdef HAVE_PTHREAD_H +#include +#endif + #endif /* !SILC_WIN32 */ #ifndef HAVE_GETOPT_LONG @@ -214,6 +218,8 @@ typedef uint32 * void *; #include "silcpkcs.h" /* SILC util library includes */ +#include "silcmutex.h" +#include "silcthread.h" #include "silchashtable.h" #include "silclog.h" #include "silcmemory.h" diff --git a/lib/silcutil/silcmutex.h b/lib/silcutil/silcmutex.h new file mode 100644 index 00000000..89ee8a55 --- /dev/null +++ b/lib/silcutil/silcmutex.h @@ -0,0 +1,119 @@ +/****h* silcutil/silcmutex.h + * + * NAME + * + * silcmutex.h + * + * COPYRIGHT + * + * 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. + * + * DESCRIPTION + * + * Interface for the SILC Mutex locking implementation. This is platform + * independent mutual exclusion interface for applications that need + * concurrency control. + * + */ + +#ifndef SILCMUTEX_H +#define SILCMUTEX_H + +/* Prototypes */ + +/****s* silcutil/SilcMutexAPI/SilcMutex + * + * NAME + * + * typedef struct SilcMutexStruct *SilcMutex; + * + * DESCRIPTION + * + * This context is the actual SILC Mutex and is allocated + * by silc_mutex_alloc and given as argument to all silc_mutex_* + * functions. It is freed by the silc_mutex_free function. + * + ***/ +typedef struct SilcMutexStruct *SilcMutex; + +/****f* silcutil/SilcMutexAPI/silc_mutex_alloc + * + * SYNOPSIS + * + * SilcMutex silc_mutex_alloc(void); + * + * DESCRIPTION + * + * Allocates SILC Mutex object. The mutex object must be allocated + * before it can be used. It is freed by the silc_mutex_free function. + * + ***/ +SilcMutex silc_mutex_alloc(void); + +/****f* silcutil/SilcMutexAPI/silc_mutex_free + * + * SYNOPSIS + * + * void silc_mutex_free(SilcMutex mutex); + * + * DESCRIPTION + * + * Free SILC Mutex object and frees all allocated memory. + * + ***/ +void silc_mutex_free(SilcMutex mutex); + +/****f* silcutil/SilcMutexAPI/silc_mutex_lock + * + * SYNOPSIS + * + * void silc_mutex_lock(SilcMutex mutex); + * + * DESCRIPTION + * + * Locks the mutex. If the mutex is locked by another thread the + * current thread will block until the other thread has issued + * silc_mutex_unlock for the mutex. + * + * NOTES + * + * The caller must not call silc_mutex_lock for mutex that has been + * already locked in the current thread. In this case deadlock will + * occur. + * + ***/ +void silc_mutex_lock(SilcMutex mutex); + +/****f* silcutil/SilcMutexAPI/silc_mutex_unlock + * + * SYNOPSIS + * + * void silc_mutex_unlock(SilcMutex mutex); + * + * DESCRIPTION + * + * Unlocks the mutex and thus releases it for another threads that + * may be waiting for the lock. + * + * NOTES + * + * The caller must not call the silc_mutex_unlock for an unlocked + * mutex or mutex not locked by the current thread. It is fatal + * error if this occurs. + * + ***/ +void silc_mutex_unlock(SilcMutex mutex); + +#endif diff --git a/lib/silcutil/silcthread.h b/lib/silcutil/silcthread.h new file mode 100644 index 00000000..5d4932d8 --- /dev/null +++ b/lib/silcutil/silcthread.h @@ -0,0 +1,148 @@ +/****h* silcutil/silcthread.h + * + * NAME + * + * silcmutex.h + * + * COPYRIGHT + * + * 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. + * + * DESCRIPTION + * + * Interface for SILC Thread implementation. This is platform independent + * implementation of threads for applications needing concurrent execution + * with the application's main thread. The threads created with this + * interface executes concurrently with the calling thread. + * + */ + +#ifndef SILCTHREAD_H +#define SILCTHREAD_H + +/* Prototypes */ + +/****s* silcutil/SilcThreadAPI/SilcThread + * + * NAME + * + * typedef struct SilcThreadStruct *SilcThread; + * + * DESCRIPTION + * + * This context is the actual SILC Thread and is returned by + * the silc_thread_create functions, and given as arguments to + * some of the silc_thread_* functions. This context and its + * resources are released automatically when the thread exits. + * + ***/ +typedef void *SilcThread; + +/****f* silcutil/SilcThreadAPI/SilcThreadStart + * + * SYNOPSIS + * + * typedef void *(*SilcThreadStart)(void *context); + * + * DESCRIPTION + * + * A callback function that is called when the thread is created + * by the silc_thread_create function. This returns the return value + * of the thread. If another thread is waiting this thread's + * destruction with silc_thread_wait the returned value is passed + * to that thread. The thread is destroyed when this function + * returns. + * + ***/ +typedef void *(*SilcThreadStart)(void *context); + +/****f* silcutil/SilcThreadAPI/silc_thread_create + * + * SYNOPSIS + * + * SilcThread silc_thread_create(SilcThreadStart start_func, void *context); + * + * DESCRIPTION + * + * Creates a new thread. The `start_func' with `context' will be + * called if the thread was created. This function returns a pointer + * to the thread or NULL if the thread could not be created. All + * resources of the returned pointer is freed automatically when the + * thread exits. + * + * If the `waitable' is set to TRUE then another thread can wait + * this thread's destruction with silc_thread_wait. If it is set to + * FALSE the thread is not waitable. + * + * NOTES + * + * If the `waitable' is TRUE the thread's resources are not freed + * when it exits until another thread has issued silc_thread_wait. + * If the `waitable' is TRUE then another thread must always issue + * silc_thread_wait to avoid memory leaks. + * + ***/ +SilcThread silc_thread_create(SilcThreadStart start_func, void *context, + bool waitable); + +/****f* silcutil/SilcThreadAPI/silc_thread_exit + * + * SYNOPSIS + * + * void silc_thread_exit(void *exit_value); + * + * DESCRIPTION + * + * Exits the current thread. This can be called to explicitly exit + * the thread with `exit_value'. Another way to exit (destroy) the + * current thread is to return from the SilcThreadStart function + * with exit value. The exit value is passed to another thread if it + * is waiting it with silc_thread_wait function. + * + ***/ +void silc_thread_exit(void *exit_value); + +/****f* silcutil/SilcThreadAPI/silc_thread_self + * + * SYNOPSIS + * + * SilcThread silc_thread_self(void); + * + * DESCRIPTION + * + * Returns a pointer of the current thread. + * + ***/ +SilcThread silc_thread_self(void); + +/****f* silcutil/SilcThreadAPI/silc_thread_wait + * + * SYNOPSIS + * + * bool silc_thread_wait(SilcThread thread, void **exit_value); + * + * DESCRIPTION + * + * Waits until the thread indicated by `thread' finishes. This blocks + * the execution of the current thread. The thread is finished if it + * calls silc_thread_exit or is destroyed naturally. When the thread + * exits its exit value is saved to `exit_value' and TRUE is returned. + * If the `thread' is not waitable this will return immediately with + * FALSE value. + * + ***/ +bool silc_thread_wait(SilcThread thread, void **exit_value); + +#endif diff --git a/lib/silcutil/unix/Makefile.am b/lib/silcutil/unix/Makefile.am index bf019fe8..1b5b1c81 100644 --- a/lib/silcutil/unix/Makefile.am +++ b/lib/silcutil/unix/Makefile.am @@ -24,6 +24,8 @@ libsilcunixutil_a_SOURCES = \ silcunixschedule.c \ silcunixnet.c \ silcunixutil.c \ - silcunixsockconn.c + silcunixsockconn.c \ + silcunixmutex.c \ + silcunixthread.c include $(top_srcdir)/Makefile.defines.in diff --git a/lib/silcutil/unix/silcunixmutex.c b/lib/silcutil/unix/silcunixmutex.c new file mode 100644 index 00000000..da802d57 --- /dev/null +++ b/lib/silcutil/unix/silcunixmutex.c @@ -0,0 +1,55 @@ +/* + + silcunixmutex.c + + 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. + +*/ +/* $Id: */ + +#include "silcincludes.h" + +#ifdef SILC_THREADS + +/* SILC Mutex structure */ +struct SilcMutexStruct { + pthread_mutex_t mutex; +}; + +SilcMutex silc_mutex_alloc(void) +{ + SilcMutex mutex = silc_calloc(1, sizeof(*mutex)); + pthread_mutex_init(&mutex->mutex, NULL); +} + +void silc_mutex_free(SilcMutex mutex) +{ + pthread_mutex_destroy(&mutex->mutex); + silc_free(mutex); +} + +void silc_mutex_lock(SilcMutex mutex) +{ + if (pthread_mutex_lock(&mutex->mutex)) + assert(FALSE); +} + +void silc_mutex_unlock(SilcMutex mutex) +{ + if (pthread_mutex_unlock(&mutex->mutex)) + assert(FALSE); +} + +#endif /* SILC_THREADS */ diff --git a/lib/silcutil/unix/silcunixthread.c b/lib/silcutil/unix/silcunixthread.c new file mode 100644 index 00000000..b4fe5a05 --- /dev/null +++ b/lib/silcutil/unix/silcunixthread.c @@ -0,0 +1,85 @@ +/* + + silcunixthread.c + + 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. + +*/ +/* $Id: */ + +#include "silcincludes.h" + +#ifdef SILC_THREADS + +SilcThread silc_thread_create(SilcThreadStart start_func, void *context, + bool waitable) +{ + pthread_attr_t attr; + pthread_t thread; + int ret; + + SILC_LOG_DEBUG(("Creating new thread")); + + if (!start_func) + return NULL; + + if (pthread_attr_init(&attr)) { + SILC_LOG_ERROR(("Thread error: %s", strerror(errno))); + return NULL; + } + + if (pthread_attr_setdetachstate(&attr, + waitable ? PTHREAD_CREATE_JOINABLE : + PTHREAD_CREATE_DETACHED)) { + SILC_LOG_ERROR(("Thread error: %s", strerror(errno))); + pthread_attr_destroy(&attr); + return NULL; + } + + ret = pthread_create(&thread, &attr, (void * (*)(void *))start_func, + context); + if (ret) { + SILC_LOG_ERROR(("Thread error: %s", strerror(errno))); + pthread_attr_destroy(&attr); + return NULL; + } + + pthread_attr_destroy(&attr); + + SILC_LOG_DEBUG(("Created thread %p", (SilcThread)ret)); + + return (SilcThread)ret; +} + +void silc_thread_exit(void *exit_value) +{ + pthread_exit(NULL); +} + +SilcThread silc_thread_self(void) +{ + pthread_t self = pthread_self(); + return (SilcThread)self; +} + +bool silc_thread_wait(SilcThread thread, void **exit_value) +{ + SILC_LOG_DEBUG(("Waiting for thread %p", thread)); + if (!pthread_join(*(pthread_t *)thread, exit_value)) + return TRUE; + return FALSE; +} + +#endif /* SILC_THREADS */