From 2c77fc43bcc40cc4786a39b14c76a481dbe66ffe Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Tue, 14 Mar 2000 09:06:10 +0000 Subject: [PATCH] Added POSIX threads support for frontend server. --- ccl/cclerrms.c | 8 +- ccl/cclfind.c | 6 +- ccl/ccltoken.c | 6 +- configure | 214 ++++++++++++++++++++++++------------------------ configure.in | 25 ++++-- include/yaz/ccl.h | 7 +- include/yaz/statserv.h | 6 +- server/statserv.c | 93 +++++++++++++++------ util/log.c | 9 +- 9 files changed, 224 insertions(+), 150 deletions(-) diff --git a/ccl/cclerrms.c b/ccl/cclerrms.c index 553af28..09ec4a5 100644 --- a/ccl/cclerrms.c +++ b/ccl/cclerrms.c @@ -45,7 +45,10 @@ * Europagate, 1995 * * $Log: cclerrms.c,v $ - * Revision 1.8 1999-11-30 13:47:11 adam + * Revision 1.9 2000-03-14 09:06:11 adam + * Added POSIX threads support for frontend server. + * + * Revision 1.8 1999/11/30 13:47:11 adam * Improved installation. Moved header files to include/yaz. * * Revision 1.7 1998/02/11 11:53:33 adam @@ -85,8 +88,7 @@ * */ -/* Chas: Required for the correct definition of ccl_err_msg */ -#include +#include static char *err_msg_array[] = { "Ok", diff --git a/ccl/cclfind.c b/ccl/cclfind.c index a4d0ba1..022d284 100644 --- a/ccl/cclfind.c +++ b/ccl/cclfind.c @@ -45,7 +45,10 @@ * Europagate, 1995 * * $Log: cclfind.c,v $ - * Revision 1.15 2000-02-24 23:49:13 adam + * Revision 1.16 2000-03-14 09:06:11 adam + * Added POSIX threads support for frontend server. + * + * Revision 1.15 2000/02/24 23:49:13 adam * Fixed memory allocation problem. * * Revision 1.14 2000/01/31 13:15:21 adam @@ -133,7 +136,6 @@ * */ -#include #include #include diff --git a/ccl/ccltoken.c b/ccl/ccltoken.c index 6e5cfdb..2376d4b 100644 --- a/ccl/ccltoken.c +++ b/ccl/ccltoken.c @@ -45,7 +45,10 @@ * Europagate, 1995 * * $Log: ccltoken.c,v $ - * Revision 1.13 2000-02-08 10:39:53 adam + * Revision 1.14 2000-03-14 09:06:11 adam + * Added POSIX threads support for frontend server. + * + * Revision 1.13 2000/02/08 10:39:53 adam * Added a few functions to set name of operands, etc. * * Revision 1.12 2000/01/31 13:15:21 adam @@ -112,7 +115,6 @@ * */ -#include #include #include diff --git a/configure b/configure index 9381f90..c37d4a0 100755 --- a/configure +++ b/configure @@ -16,7 +16,7 @@ ac_help="$ac_help ac_help="$ac_help --enable-tcpd enable TCP wrapper for server if available" ac_help="$ac_help - --enable-threads enable threads if available" + --disable-threads disable threads" # Initialize some variables set by options. # The variables have the same names as the options, with @@ -1588,6 +1588,61 @@ fi done fi +for ac_func in vsnprintf +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:1595: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:1623: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + # Check whether --enable-tcpd or --disable-tcpd was given. if test "${enable_tcpd+set}" = set; then enableval="$enable_tcpd" @@ -1596,11 +1651,11 @@ fi if test "$enable_tcpd" = "yes"; then echo $ac_n "checking for working tcpd.h""... $ac_c" 1>&6 -echo "configure:1600: checking for working tcpd.h" >&5 +echo "configure:1655: checking for working tcpd.h" >&5 oldLibs=$LIBS LIBS="$LIBS -lwrap -lnsl" cat > conftest.$ac_ext < #include @@ -1611,7 +1666,7 @@ struct request_info request_info; int i; i = hosts_access(&request_info); ; return 0; } EOF -if { (eval echo configure:1615: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1670: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* tcpd_ok=1 else @@ -1633,12 +1688,12 @@ EOF fi fi echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -echo "configure:1637: checking for ANSI C header files" >&5 +echo "configure:1692: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -1646,7 +1701,7 @@ else #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1650: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1705: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -1663,7 +1718,7 @@ rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -1681,7 +1736,7 @@ fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -1702,7 +1757,7 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') @@ -1713,7 +1768,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF -if { (eval echo configure:1717: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:1772: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else @@ -1742,101 +1797,14 @@ fi # Check whether --enable-threads or --disable-threads was given. if test "${enable_threads+set}" = set; then enableval="$enable_threads" - : -fi - -if test "$enable_threads" = "yes"; then - for ac_hdr in pthread.h threads.h -do -ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` -echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:1754: checking for $ac_hdr" >&5 -if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1764: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` -if test -z "$ac_err"; then - rm -rf conftest* - eval "ac_cv_header_$ac_safe=yes" -else - echo "$ac_err" >&5 - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_header_$ac_safe=no" -fi -rm -f conftest* -fi -if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then - echo "$ac_t""yes" 1>&6 - ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` - cat >> confdefs.h <&6 -fi -done - - echo $ac_n "checking for pthread_mutex_lock""... $ac_c" 1>&6 -echo "configure:1791: checking for pthread_mutex_lock" >&5 -if eval "test \"`echo '$''{'ac_cv_func_pthread_mutex_lock'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -/* Override any gcc2 internal prototype to avoid an error. */ -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char pthread_mutex_lock(); - -int main() { - -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_pthread_mutex_lock) || defined (__stub___pthread_mutex_lock) -choke me -#else -pthread_mutex_lock(); -#endif - -; return 0; } -EOF -if { (eval echo configure:1819: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_func_pthread_mutex_lock=yes" + enable_threads=$enableval else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_func_pthread_mutex_lock=no" -fi -rm -f conftest* + enable_threads=yes fi -if eval "test \"`echo '$ac_cv_func_'pthread_mutex_lock`\" = yes"; then - echo "$ac_t""yes" 1>&6 - : -else - echo "$ac_t""no" 1>&6 -fi - - if test "$ac_cv_func_pthread_mutex_lock" = "no"; then - echo $ac_n "checking for main in -lpthread""... $ac_c" 1>&6 -echo "configure:1840: checking for main in -lpthread" >&5 +if test "$enable_threads" = "yes"; then + echo $ac_n "checking for main in -lpthread""... $ac_c" 1>&6 +echo "configure:1808: checking for main in -lpthread" >&5 ac_lib_var=`echo pthread'_'main | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1844,14 +1812,14 @@ else ac_save_LIBS="$LIBS" LIBS="-lpthread $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1823: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1878,11 +1846,43 @@ else echo "$ac_t""no" 1>&6 fi - fi - cat >> confdefs.h <<\EOF + echo $ac_n "checking for working POSIX Threads""... $ac_c" 1>&6 +echo "configure:1851: checking for working POSIX Threads" >&5 + cat > conftest.$ac_ext < + int func(void *p) { return 0; } + +int main() { + + pthread_t pthread_id; + int r = pthread_create (&pthread_id, 0, func, 0); +; return 0; } +EOF +if { (eval echo configure:1864: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + thread_ok=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + thread_ok=no +fi +rm -f conftest* + if test "$thread_ok" = "yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_PTHREAD_H 1 +EOF + + cat >> confdefs.h <<\EOF #define _REENTRANT 1 EOF + else + echo "$ac_t""no" 1>&6 + fi fi SUBDIRS_VAR="util odr $ASNMODULE $ILLMODULE zutil comstack ccl tab retrieval server include lib client ztest" diff --git a/configure.in b/configure.in index 0b07849..58ebe0b 100644 --- a/configure.in +++ b/configure.in @@ -1,7 +1,7 @@ dnl YAZ Toolkit dnl (c) Index Data 1994-2000 dnl See the file LICENSE for details. -dnl $Id: configure.in,v 1.23 2000-03-10 08:41:30 adam Exp $ +dnl $Id: configure.in,v 1.24 2000-03-14 09:06:11 adam Exp $ AC_INIT(include/yaz/yaz-version.h) AM_INIT_AUTOMAKE(yaz, 1.6) dnl @@ -52,6 +52,8 @@ AC_CHECK_LIB(history, add_history, [LIBS="$LIBS -lhistory"]) if test "$ac_cv_lib_readline_readline" = "yes"; then AC_CHECK_HEADERS(readline/readline.h readline/history.h) fi +dnl ------ snprintf +AC_CHECK_FUNCS(vsnprintf) dnl dnl ------ tcpd AC_ARG_ENABLE(tcpd,[ --enable-tcpd enable TCP wrapper for server if available]) @@ -81,14 +83,23 @@ if test "$ac_cv_header_stdc" = "no"; then fi dnl dnl ------ Threads -AC_ARG_ENABLE(threads, [ --enable-threads enable threads if available]) +AC_ARG_ENABLE(threads, [ --disable-threads disable threads],[enable_threads=$enableval],[enable_threads=yes]) if test "$enable_threads" = "yes"; then - AC_CHECK_HEADERS(pthread.h threads.h) - AC_CHECK_FUNC(pthread_mutex_lock) - if test "$ac_cv_func_pthread_mutex_lock" = "no"; then - AC_CHECK_LIB(pthread, main) + AC_CHECK_LIB(pthread,main) + AC_MSG_CHECKING(for working POSIX Threads) + AC_TRY_LINK([#include + int func(void *p) { return 0; } + ],[ + pthread_t pthread_id; + int r = pthread_create (&pthread_id, 0, func, 0);], + thread_ok=yes,thread_ok=no) + if test "$thread_ok" = "yes"; then + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_PTHREAD_H) + AC_DEFINE(_REENTRANT) + else + AC_MSG_RESULT(no) fi - AC_DEFINE(_REENTRANT) fi dnl SUBDIRS_VAR="util odr $ASNMODULE $ILLMODULE zutil comstack ccl tab retrieval server include lib client ztest" diff --git a/include/yaz/ccl.h b/include/yaz/ccl.h index 89bdab2..53cd583 100644 --- a/include/yaz/ccl.h +++ b/include/yaz/ccl.h @@ -46,7 +46,10 @@ * CCL - header file * * $Log: ccl.h,v $ - * Revision 1.3 2000-02-08 10:39:53 adam + * Revision 1.4 2000-03-14 09:06:11 adam + * Added POSIX threads support for frontend server. + * + * Revision 1.3 2000/02/08 10:39:53 adam * Added a few functions to set name of operands, etc. * * Revision 1.2 2000/01/31 13:15:21 adam @@ -114,6 +117,8 @@ #ifndef CCL_H #define CCL_H +#include + #ifdef __cplusplus extern "C" { #endif diff --git a/include/yaz/statserv.h b/include/yaz/statserv.h index 0887122..f900888 100644 --- a/include/yaz/statserv.h +++ b/include/yaz/statserv.h @@ -24,7 +24,10 @@ * OF THIS SOFTWARE. * * $Log: statserv.h,v $ - * Revision 1.2 2000-02-28 11:20:06 adam + * Revision 1.3 2000-03-14 09:06:11 adam + * Added POSIX threads support for frontend server. + * + * Revision 1.2 2000/02/28 11:20:06 adam * Using autoconf. New definitions: YAZ_BEGIN_CDECL/YAZ_END_CDECL. * * Revision 1.1 1999/11/30 13:47:11 adam @@ -106,6 +109,7 @@ YAZ_BEGIN_CDECL typedef struct statserv_options_block { int dynamic; /* fork on incoming requests */ + int threads; /* use threads */ int one_shot; /* one session then exit(1) */ int loglevel; /* desired logging-level */ char apdufile[ODR_MAXNAME+1]; /* file for pretty-printed PDUs */ diff --git a/server/statserv.c b/server/statserv.c index 000ebd8..0ef6878 100644 --- a/server/statserv.c +++ b/server/statserv.c @@ -7,7 +7,10 @@ * Chas Woodfield, Fretwell Downing Datasystems. * * $Log: statserv.c,v $ - * Revision 1.59 1999-11-30 13:47:12 adam + * Revision 1.60 2000-03-14 09:06:11 adam + * Added POSIX threads support for frontend server. + * + * Revision 1.59 1999/11/30 13:47:12 adam * Improved installation. Moved header files to include/yaz. * * Revision 1.58 1999/08/27 09:40:32 adam @@ -215,6 +218,9 @@ #include #include "service.h" #else +#if HAVE_PTHREAD_H +#include +#endif #include #include #endif @@ -242,6 +248,7 @@ static char *me = "statserver"; int check_options(int argc, char **argv); statserv_options_block control_block = { 1, /* dynamic mode */ + 0, /* threaded mode */ 0, /* one shot (single session) */ LOG_DEFAULT_LEVEL, /* log level */ "", /* no PDUs */ @@ -534,10 +541,11 @@ void statserv_closedown() iochan_destroy(p); } +static void *new_session (void *vp); + static void listener(IOCHAN h, int event) { COMSTACK line = (COMSTACK) iochan_getdata(h); - association *newas; static int hand[2]; static int child = 0; int res; @@ -617,8 +625,6 @@ static void listener(IOCHAN h, int event) else if (event == EVENT_OUTPUT) { COMSTACK new_line; - IOCHAN new_chan; - char *a; if (!(new_line = cs_accept(line))) { @@ -643,26 +649,19 @@ static void listener(IOCHAN h, int event) } else iochan_setflags(h, EVENT_INPUT | EVENT_EXCEPT); /* reset listener */ - - if (!(new_chan = iochan_create(cs_fileno(new_line), ir_session, - EVENT_INPUT))) - { - yaz_log(LOG_FATAL, "Failed to create iochan"); - iochan_destroy(h); - return; - } - new_chan->next = pListener; - pListener = new_chan; - if (!(newas = create_association(new_chan, new_line))) + +#if HAVE_PTHREAD_H + if (control_block.threads) { - yaz_log(LOG_FATAL, "Failed to create new assoc."); - iochan_destroy(h); - return; + pthread_t child_thread; + pthread_create (&child_thread, 0, new_session, new_line); + pthread_detach (child_thread); } - iochan_setdata(new_chan, newas); - iochan_settimeout(new_chan, control_block.idle_timeout * 60); - a = cs_addrstr(new_line); - yaz_log(LOG_LOG, "Accepted connection from %s", a ? a : "[Unknown]"); + else + new_session(new_line); +#else + new_session(new_line); +#endif } else { @@ -672,6 +671,39 @@ static void listener(IOCHAN h, int event) } } +static void *new_session (void *vp) +{ + char *a; + association *newas; + IOCHAN new_chan; + COMSTACK new_line = (COMSTACK) vp; + if (!(new_chan = iochan_create(cs_fileno(new_line), ir_session, + EVENT_INPUT))) + { + yaz_log(LOG_FATAL, "Failed to create iochan"); + return 0; + } + if (!(newas = create_association(new_chan, new_line))) + { + yaz_log(LOG_FATAL, "Failed to create new assoc."); + return 0; + } + iochan_setdata(new_chan, newas); + iochan_settimeout(new_chan, control_block.idle_timeout * 60); + a = cs_addrstr(new_line); + yaz_log(LOG_LOG, "Accepted connection from %s", a ? a : "[Unknown]"); + if (control_block.threads) + { + event_loop(&new_chan); + } + else + { + new_chan->next = pListener; + pListener = new_chan; + } + return 0; +} + #endif /* WIN32 */ static void inetd_connection(int what) @@ -743,7 +775,8 @@ static void add_listener(char *where, int what) return; } yaz_log(LOG_LOG, "Adding %s %s listener on %s", - control_block.dynamic ? "dynamic" : "static", + control_block.dynamic ? "dynamic" : + (control_block.threads ? "threaded" : "static"), what == PROTO_SR ? "SR" : "Z3950", where); if (!(l = cs_create(type, 0, what))) { @@ -868,7 +901,7 @@ int check_options(int argc, char **argv) int ret = 0, r; char *arg; - while ((ret = options("1a:iszSl:v:u:c:w:t:k:d:", argv, argc, &arg)) != -2) + while ((ret = options("1a:iszSTl:v:u:c:w:t:k:d:", argv, argc, &arg)) != -2) { switch (ret) { @@ -888,6 +921,14 @@ int check_options(int argc, char **argv) case 'S': control_block.dynamic = 0; break; + case 'T': +#if HAVE_PTHREAD_H + control_block.dynamic = 0; + control_block.threads = 1; +#else + fprintf(stderr, "%s: Threaded mode not available.\n", me); +#endif + break; case 'l': strcpy(control_block.logfile, arg ? arg : ""); log_init(control_block.loglevel, me, control_block.logfile); @@ -935,10 +976,10 @@ int check_options(int argc, char **argv) } break; default: - fprintf(stderr, "Usage: %s [ -i -a -v " + fprintf(stderr, "Usage: %s [ -a -v " " -l -u -c -t " " -k -d " - " -zsS -w ... ]\n", me); + " -zsiST -w ... ]\n", me); return(1); } } diff --git a/util/log.c b/util/log.c index b2b8c0d..53b85d3 100644 --- a/util/log.c +++ b/util/log.c @@ -4,7 +4,10 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: log.c,v $ - * Revision 1.22 2000-02-29 13:44:55 adam + * Revision 1.23 2000-03-14 09:06:11 adam + * Added POSIX threads support for frontend server. + * + * Revision 1.22 2000/02/29 13:44:55 adam * Check for config.h (currently not generated). * * Revision 1.21 2000/02/28 11:20:06 adam @@ -229,7 +232,11 @@ void yaz_log(int level, const char *fmt, ...) level -= mask_names[i].mask; } va_start(ap, fmt); +#if HAVE_VSNPRINTF + vsnprintf(buf, sizeof(buf), fmt, ap); +#else vsprintf(buf, fmt, ap); +#endif if (o_level & LOG_ERRNO) sprintf(buf + strlen(buf), " [%s]", strerror(errno)); if (start_hook_func) -- 1.7.10.4