From: Kurt Zeilenga Date: Sun, 20 Dec 1998 00:58:55 +0000 (+0000) Subject: Provide framework for ldap_r and reentrant/thread safety levels. X-Git-Tag: OPENLDAP_SLAPD_BACK_LDAP~913 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=8aba5c5059645e657016eee3d3d68e1c67b99b13;p=openldap Provide framework for ldap_r and reentrant/thread safety levels. -lldap_r can now be implemented... --- diff --git a/acconfig.h b/acconfig.h index 6c85b29c28..686ef47bf9 100644 --- a/acconfig.h +++ b/acconfig.h @@ -174,6 +174,8 @@ /* These are defined in ldap_features.h */ /* + LDAP_API_FEATURE_X_OPENLDAP_REENTRANT + LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE LDAP_API_FEATURE_X_OPENLDAP_V2_DNS LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS */ diff --git a/build/lib.mk b/build/lib.mk index d92d72503d..955a67d859 100644 --- a/build/lib.mk +++ b/build/lib.mk @@ -23,11 +23,11 @@ lint5: lint5-local FORCE clean-common: FORCE $(RM) $(LIBRARY) ../$(LIBRARY) $(XLIBRARY) \ - $(PROGRAMS) $(XPROGRAMS) $(XSRCS) \ + $(PROGRAMS) $(XPROGRAMS) $(XSRCS) $(XXSRCS) \ *.o *.lo a.out core version.c .libs/* depend-common: FORCE - $(MKDEP) $(DEFS) $(DEFINES) $(SRCS) + $(MKDEP) $(DEFS) $(DEFINES) $(SRCS) $(XXSRCS) lint-local: FORCE lint5-local: FORCE diff --git a/configure b/configure index 31c55b2c5e..8fae424123 100755 --- a/configure +++ b/configure @@ -7779,11 +7779,9 @@ fi for ac_func in \ bcopy \ - ctime_r \ flock \ getdtablesize \ gethostname \ - gethostbyaddr_r gethostbyname_r \ getpwuid \ gettimeofday \ lockf \ @@ -7804,7 +7802,6 @@ for ac_func in \ strsep \ strstr \ strtok \ - strtok_r \ strtol \ strtoul \ sysconf \ @@ -7812,12 +7809,12 @@ for ac_func in \ do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7816: checking for $ac_func" >&5 +echo "configure:7813: 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 <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:7841: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7865,15 +7862,96 @@ fi done +# these functions are required to build a thread_safe -lldap +for ac_func in \ + strtok_r \ + ctime_r \ + gethostbyaddr_r \ + gethostbyname_r \ + +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:7875: 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:7903: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; 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 + + +if test $ac_cv_func_strtok_r = yes \ + -a $ac_cv_func_ctime_r = yes \ + -a $ac_cv_func_gethostbyaddr_r = yes \ + -a $ac_cv_func_gethostbyname_r = yes \ + ; then + + cat >> confdefs.h <<\EOF +#define LDAP_API_FEATURE_X_OPENLDAP_REENTRANT 1 +EOF + +fi + +if test $ol_link_threads != no ; then + cat >> confdefs.h <<\EOF +#define LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE 1 +EOF + +fi + for ac_func in getopt strdup tempnam do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7872: checking for $ac_func" >&5 +echo "configure:7950: 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 <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:7978: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7926,13 +8004,13 @@ done # Check Configuration echo $ac_n "checking declaration of sys_errlist""... $ac_c" 1>&6 -echo "configure:7930: checking declaration of sys_errlist" >&5 +echo "configure:8008: checking declaration of sys_errlist" >&5 if eval "test \"`echo '$''{'ol_cv_dcl_sys_errlist'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -7942,7 +8020,7 @@ int main() { char *c = (char *) *sys_errlist ; return 0; } EOF -if { (eval echo configure:7946: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:8024: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ol_cv_dcl_sys_errlist=yes else @@ -7963,20 +8041,20 @@ if test $ol_cv_dcl_sys_errlist = no ; then EOF echo $ac_n "checking existence of sys_errlist""... $ac_c" 1>&6 -echo "configure:7967: checking existence of sys_errlist" >&5 +echo "configure:8045: checking existence of sys_errlist" >&5 if eval "test \"`echo '$''{'ol_cv_have_sys_errlist'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { char *c = (char *) *sys_errlist ; return 0; } EOF -if { (eval echo configure:7980: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:8058: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* ol_cv_have_sys_errlist=yes else diff --git a/configure.in b/configure.in index d7de1b6f20..f33d501642 100644 --- a/configure.in +++ b/configure.in @@ -808,13 +808,33 @@ dnl #if defined( HAVE_REENTRANT_FUNCTIONS ) \ dnl || defined( HAVE_FUNC_R ) dnl func_r(...); dnl #else -dnl func(...); +dnl # if defined( HAVE_THREADS ) +dnl /* lock */ +dnl # endif +dnl func(...); +dnl # if defined( HAVE_THREADS ) +dnl /* unlock */ +dnl # endif dnl #endif dnl dnl HAVE_REENTRANT_FUNCTIONS is derived from: dnl _POSIX_REENTRANT_FUNCTIONS dnl _POSIX_THREAD_SAFE_FUNCTIONS dnl _POSIX_THREADSAFE_FUNCTIONS +dnl +dnl and is currently defined in lthread.h +dnl +dnl HAVE_THREADS is defined by lthread.h iff -UNO_THREADS +dnl +dnl libldap/*.c should only include iff +dnl LDAP_R_COMPILE is defined. ie: +dnl #ifdef LDAP_R_COMPILE +dnl # include LDAP_R_COMPILE +dnl #endif +dnl +dnl LDAP_R_COMIPLE is defined by libldap_r/Makefile.in +dnl specifically for compiling the threadsafe version of +dnl the ldap library (-lldap_r). dnl dnl dnl check for reentrant/threadsafe functions dnl dnl @@ -1116,11 +1136,9 @@ AC_FUNC_WAIT3 AC_CHECK_FUNCS( \ bcopy \ - ctime_r \ flock \ getdtablesize \ gethostname \ - gethostbyaddr_r gethostbyname_r \ getpwuid \ gettimeofday \ lockf \ @@ -1141,13 +1159,33 @@ AC_CHECK_FUNCS( \ strsep \ strstr \ strtok \ - strtok_r \ strtol \ strtoul \ sysconf \ waitpid \ ) +# these functions are required to build a thread_safe -lldap +AC_CHECK_FUNCS( \ + strtok_r \ + ctime_r \ + gethostbyaddr_r \ + gethostbyname_r \ +) + +if test $ac_cv_func_strtok_r = yes \ + -a $ac_cv_func_ctime_r = yes \ + -a $ac_cv_func_gethostbyaddr_r = yes \ + -a $ac_cv_func_gethostbyname_r = yes \ + ; then + + AC_DEFINE(LDAP_API_FEATURE_X_OPENLDAP_REENTRANT, 1) +fi + +if test $ol_link_threads != no ; then + AC_DEFINE(LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE, 1) +fi + dnl We actually may need to replace more than this. AC_REPLACE_FUNCS(getopt strdup tempnam) diff --git a/include/ldap.h b/include/ldap.h index 5a53ef2c1d..5fb02d29d0 100644 --- a/include/ldap.h +++ b/include/ldap.h @@ -40,6 +40,19 @@ LDAP_BEGIN_DECL /* include LDAP_API_FEATURE defines */ #include +#if defined( LDAP_API_FEATURE_X_OPENLDAP_REENTRANT ) || \ + ( defined( LDAP_THREAD_SAFE ) && \ + defined( LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE ) ) + /* -lldap may or may not be thread safe */ + /* -lldap_r, if available, is always thread safe */ +# define LDAP_API_FEATURE_THREAD_SAFE 1 +#endif +#if defined( LDAP_THREAD_SAFE ) && \ + defined( LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE ) +/* #define LDAP_API_FEATURE_SESSION_SAFE 1 */ +/* #define LDAP_API_OPERATION_SESSION_SAFE 1 */ +#endif + #define LDAP_COMPAT20 #define LDAP_COMPAT30 #if defined(LDAP_COMPAT20) || defined(LDAP_COMPAT30) diff --git a/include/ldap_features.h.in b/include/ldap_features.h.in index 105aaeb495..e3f273f8ff 100644 --- a/include/ldap_features.h.in +++ b/include/ldap_features.h.in @@ -4,6 +4,39 @@ #ifndef _LDAP_FEATURES_H #define _LDAP_FEATURES_H 1 +/* +** OpenLDAP reentrancy/thread-safeness should be dynamically +** checked using ldap_get_option(). +** +** The -lldap implementation may or may not be: +** LDAP_API_FEATURE_THREAD_SAFE +** +** The preprocessor flag LDAP_API_FEATURE_X_OPENLDAP_REENTRANT can +** be used to determine if -lldap is LDAP_API_FEATURE_THREAD_SAFE at +** compile time. +** +** The -lldap_r implementation is always THREAD_SAFE but +** may also be: +** LDAP_API_FEATURE_SESSION_THREAD_SAFE +** LDAP_API_FEATURE_OPERATION_THREAD_SAFE +** +** The preprocessor flag LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE +** can be used to determine if -lldap_r is availalbe at compile +** time. You must define LDAP_THREAD_SAFE if and only if you +** link with -lldap_r. +** +** If you fail to define LDAP_THREAD_SAFE when linking with +** -lldap_r or define LDAP_THREAD_SAFE when linking with -lldap, +** provided header definations and declarations may be incorrect. +** +*/ + +/* is -lldap reentrant or not */ +#undef LDAP_API_FEATURE_X_OPENLDAP_REENTRANT + +/* is threadsafe version of -lldap (ie: -lldap_r) *available* or not */ +#undef LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE + /* LDAP v2 DNS */ #undef LDAP_API_FEATURE_X_OPENLDAP_V2_DNS diff --git a/include/lthread.h b/include/lthread.h index 3485406d93..b33900f98c 100644 --- a/include/lthread.h +++ b/include/lthread.h @@ -19,6 +19,12 @@ LDAP_BEGIN_DECL +#if defined( _POSIX_REENTRANT_FUNCTIONS ) || \ + defined( _POSIX_THREAD_SAFE_FUNCTIONS ) || \ + defined( _POSIX_THREAD_SAFE_FUNCTIONS ) +#define HAVE_REENTRANT_FUNCTIONS 1 +#endif + #if !defined( HAVE_PTHREAD_ATTR_INIT ) && \ defined( HAVE_PTHREAD_ATTR_CREATE ) #define pthread_attr_init( a ) pthread_attr_create( a ) @@ -103,6 +109,8 @@ LDAP_END_DECL LDAP_BEGIN_DECL +#define HAVE_REENTRANT_FUNCTIONS 1 + typedef void *(*VFP)(); /* default attr states */ @@ -145,6 +153,8 @@ LDAP_END_DECL LDAP_BEGIN_DECL +#define HAVE_REENTRANT_FUNCTIONS 1 + stkalign_t *get_stack( int *stacknop ); void free_stack( int *stackno ); @@ -265,4 +275,9 @@ typedef int pthread_cond_t; LDAP_END_DECL #endif /* no threads support */ + +#ifndef NO_THREADS +# define HAVE_THREADS 1 +#endif + #endif /* _LTHREAD_H */ diff --git a/include/portable.h.in b/include/portable.h.in index f4785d5f91..d2c7f0996d 100644 --- a/include/portable.h.in +++ b/include/portable.h.in @@ -263,6 +263,8 @@ is provided ``as is'' without express or implied warranty. /* These are defined in ldap_features.h */ /* + LDAP_API_FEATURE_X_OPENLDAP_REENTRANT + LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE LDAP_API_FEATURE_X_OPENLDAP_V2_DNS LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS */ diff --git a/libraries/libldap/ldap-int.h b/libraries/libldap/ldap-int.h index 68c8c5b245..7948578895 100644 --- a/libraries/libldap/ldap-int.h +++ b/libraries/libldap/ldap-int.h @@ -8,11 +8,13 @@ #ifndef _LDAP_INT_H #define _LDAP_INT_H 1 +#ifdef LDAP_COMPILING_R +#define LDAP_THREAD_SAFE 1 +#endif + #include "../liblber/lber-int.h" #include "ldap_log.h" #include "ldap.h" -#include -#include LDAP_BEGIN_DECL @@ -280,6 +282,8 @@ int ldap_8859_to_t61( char **bufp, unsigned long *buflenp, int free_input ); * */ +struct hostent; /* avoid pulling in */ + extern char *ldap_int_strtok( char *str, const char *delim, char **pos ); extern char *ldap_int_ctime( const time_t *tp, char *buf ); extern int ldap_int_gethostbyname_a( diff --git a/libraries/libldap/options.c b/libraries/libldap/options.c index 07374e228c..c595972bc2 100644 --- a/libraries/libldap/options.c +++ b/libraries/libldap/options.c @@ -9,6 +9,22 @@ #include "ldap-int.h" static const char* features[] = { +#ifdef LDAP_API_FEATURE_THREAD_SAFE + "THREAD_SAFE", +#endif +#ifdef LDAP_API_FEATURE_SESSION_THREAD_SAFE + "SESSION_THREAD_SAFE", +#endif +#ifdef LDAP_API_FEATURE_OPERATION_THREAD_SAFE + "OPERATION_THREAD_SAFE", +#endif +#ifdef LDAP_API_FEATURE_X_OPENLDAP_REEENTRANT + "X_OPENLDAP_REENTRANT", +#endif +#if defined( LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE ) && \ + defined( LDAP_THREAD_SAFE ) + "X_OPENLDAP_THREAD_SAFE", +#endif #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_DNS "X_OPENLDAP_V2_DNS", #endif diff --git a/libraries/libldap_r/Makefile.in b/libraries/libldap_r/Makefile.in index 9706efb868..f5a28dba9a 100644 --- a/libraries/libldap_r/Makefile.in +++ b/libraries/libldap_r/Makefile.in @@ -4,12 +4,10 @@ LIBRARY = libldap_r.la XLIBRARY = ../libldap_r.a -XDIR = ../libldap -XDEFS = -DLDAP_THREAD_SAFE -I$(XDIR) - PROGRAMS = apitest ltest ttest -XSRCS = apitest.c test.c tmpltest.c \ +XXDIR = ../libldap +XXSRCS = apitest.c test.c tmpltest.c \ bind.c open.c result.c error.c compare.c search.c \ modify.c add.c modrdn.c delete.c abandon.c ufn.c cache.c \ getfilter.c sbind.c kbind.c unbind.c friendly.c cldap.c \ @@ -28,19 +26,22 @@ OBJS = bind.lo open.lo result.lo error.lo compare.lo search.lo \ LDAP_INCDIR= ../../include LDAP_LIBDIR= ../../libraries +XDEFS = -DLDAP_R_COMPILE -I$(XXDIR) LIBS = $(LDAP_LIBPATH) $(LDAP_LIBLDAP) $(LDAP_LIBLBER) $(AC_LIBS) -.links : - @for i in $(XSRCS); do \ +.links : FORCE + @for i in $(XXSRCS); do \ $(RM) $$i ; \ - $(LN_S) $(XDIR)/$$i . ; \ + $(LN_S) $(XXDIR)/$$i . ; \ done touch .links -$(XSRCS) : .links +$(XXSRCS) : .links clean-local: FORCE - $(RM) .links + @$(RM) .links + +depend-common: .links apitest: $(LIBRARY) apitest.o $(LDAP_LIBLBER_DEPEND) $(LTLINK) $(LDFLAGS) -o $@ apitest.o $(LIBS)