[shibboleth-sp2] 24/100: Implemented thread-safe wrappers around global data.

Ferenc Wágner wferi-guest at moszumanska.debian.org
Tue Jan 26 21:29:14 UTC 2016


This is an automated email from the git hooks/post-receive script.

wferi-guest pushed a commit to annotated tag 1.2.1
in repository shibboleth-sp2.

commit 1f42cf288b16525872e2491fc2549c7040852a20
Author: Scott Cantor <cantor.2 at osu.edu>
Date:   Mon Oct 11 22:01:40 2004 +0000

    Implemented thread-safe wrappers around global data.
---
 oncrpc/nt.c       |  25 +++++++++++++
 oncrpc/oncrpc.def |   7 ++--
 oncrpc/rpc/auth.h |   4 +-
 oncrpc/rpc/clnt.h |   6 ++-
 oncrpc/rpc/rpc.h  |  21 ++++++++++-
 oncrpc/rpc/svc.h  |  16 ++------
 oncrpc/rpc_comm.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++++-----
 oncrpc/svc.c      |  11 +++---
 oncrpc/svc_run.c  |   2 +-
 9 files changed, 163 insertions(+), 38 deletions(-)

diff --git a/oncrpc/nt.c b/oncrpc/nt.c
index 280df72..99ef500 100644
--- a/oncrpc/nt.c
+++ b/oncrpc/nt.c
@@ -38,6 +38,31 @@ int rpc_nt_exit(void)
     return WSACleanup();
 }
 
+BOOL WINAPI DllMain(
+  HINSTANCE hinstDLL,
+  DWORD fdwReason,
+  LPVOID lpvReserved
+)
+{
+    switch (fdwReason) {
+        case DLL_PROCESS_ATTACH:
+            __thr_key = TlsAlloc();
+            break;
+
+        case DLL_PROCESS_DETACH:
+            TlsFree(__thr_key);
+            break;
+
+        case DLL_THREAD_DETACH: {
+            LPVOID ptr=TlsGetValue(__thr_key);
+            if (ptr)
+                free(ptr);
+            }
+            break;
+    }
+    return TRUE;
+}
+
 VOID
 nt_rpc_report(LPTSTR lpszMsg)
 {
diff --git a/oncrpc/oncrpc.def b/oncrpc/oncrpc.def
index ccdbee3..e46a54b 100644
--- a/oncrpc/oncrpc.def
+++ b/oncrpc/oncrpc.def
@@ -85,6 +85,7 @@ xdrrec_skiprecord
 xdrstdio_create
 xprt_register
 xprt_unregister
-onc_svc_fdset DATA
-rpc_createerr DATA
-_null_auth DATA
+DllMain
+_thr_svc_fdset
+_thr_rpc_createerr
+_thr_null_auth
diff --git a/oncrpc/rpc/auth.h b/oncrpc/rpc/auth.h
index 64e9c78..20f9353 100644
--- a/oncrpc/rpc/auth.h
+++ b/oncrpc/rpc/auth.h
@@ -165,6 +165,7 @@ typedef struct {
 #define auth_destroy(auth)		\
 		((*((auth)->ah_ops->ah_destroy))(auth))
 
+/*
 #ifdef WIN32
 #ifdef ONCRPCDLL
 extern struct opaque_auth _null_auth;
@@ -178,7 +179,8 @@ _declspec(dllimport) struct opaque_auth _null_auth;
 #else
 extern struct opaque_auth _null_auth;
 #endif
-
+*/
+#define _null_auth (*_thr_null_auth())
 
 /*
  * These are the various implementations of client side authenticators.
diff --git a/oncrpc/rpc/clnt.h b/oncrpc/rpc/clnt.h
index d6b51b8..a671088 100644
--- a/oncrpc/rpc/clnt.h
+++ b/oncrpc/rpc/clnt.h
@@ -327,11 +327,12 @@ char *clnt_sperror(/* CLIENT *clnt, char *msg */DOTS);	/* string */
 /* 
  * If a creation fails, the following allows the user to figure out why.
  */
-struct rpc_createerr {
+struct rpc_createerr_t {
 	enum clnt_stat cf_stat;
 	struct rpc_err cf_error; /* useful when cf_stat == RPC_PMAPFAILURE */
 };
 
+/*
 #ifdef WIN32
 #ifdef ONCRPCDLL
 extern struct rpc_createerr rpc_createerr;
@@ -345,7 +346,8 @@ _declspec(dllimport) struct rpc_createerr rpc_createerr;
 #else
 extern struct rpc_createerr rpc_createerr;
 #endif
-
+*/
+#define rpc_createerr (*_thr_rpc_createerr())
 
 /*
  * Copy error message to buffer.
diff --git a/oncrpc/rpc/rpc.h b/oncrpc/rpc/rpc.h
index d6c1560..6b6cbfc 100644
--- a/oncrpc/rpc/rpc.h
+++ b/oncrpc/rpc/rpc.h
@@ -54,15 +54,15 @@
 
 #define clnttcp_create	onc_clnttcp_create
 #define clnt_spcreateerror	onc_clnt_spcreateerror
-
-#define svcfd_create	onc_svcfd_create
 #define svc_register	onc_svc_register
 #define svc_getreqset	onc_svc_getreqset
+#define svcfd_create    onc_svcfd_create
 
 #ifndef FD_SETSIZE
 # define FD_SETSIZE 1024
 #endif
 
+
 #ifdef WIN32
 
 #include <stdlib.h>
@@ -128,4 +128,21 @@ extern int xdr_opaque_auth(DOTS);
 /* routines for parsing /etc/rpc */
 #include <rpc/netdb.h>		/* structures and routines to parse /etc/rpc */
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Oct 2004: Additions by Scott Cantor to support POSIX and Win32 threads. */
+#ifdef WIN32
+extern DWORD __thr_key; /* Win32 TLS key */
+#endif
+
+extern struct opaque_auth* _thr_null_auth(void);
+extern struct rpc_createerr_t* _thr_rpc_createerr(void);
+extern fd_set* _thr_svc_fdset(void);
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* ndef __RPC_HEADER__ */
diff --git a/oncrpc/rpc/svc.h b/oncrpc/rpc/svc.h
index 33ffd6b..eec126d 100644
--- a/oncrpc/rpc/svc.h
+++ b/oncrpc/rpc/svc.h
@@ -253,20 +253,10 @@ extern void	svcerr_systemerr(DOTS);
  * dynamic; must be inspected before each call to select 
  */
 #ifdef FD_SETSIZE
-#ifdef WIN32
-#ifdef ONCRPCDLL
-extern fd_set onc_svc_fdset;
-#else
-#ifdef __BORLANDC__
-extern __import fd_set onc_svc_fdset;
-#else
-_declspec(dllimport) fd_set onc_svc_fdset;
-#endif
-#endif
-#else
-extern fd_set onc_svc_fdset;
+#define svc_fdset (*_thr_svc_fdset())
+#ifndef WIN32
+#define svc_fds svc_fdset.fds_bits[0]	/* compatibility */
 #endif
-#define svc_fds onc_svc_fdset.fds_bits[0]	/* compatibility */
 #else
 extern int svc_fds;
 #endif /* def FD_SETSIZE */
diff --git a/oncrpc/rpc_comm.c b/oncrpc/rpc_comm.c
index d10cfeb..155d952 100644
--- a/oncrpc/rpc_comm.c
+++ b/oncrpc/rpc_comm.c
@@ -43,19 +43,108 @@
  * This file should only contain common data (global data) that is exported
  * by public interfaces 
  */
-#if defined(WIN32) && defined(__BORLANDC__)
-__declspec(dllexport)
+
+/* modified by Scott Cantor to make global data per-thread */
+
+#ifndef WIN32
+#include <pthread.h>
+pthread_once_t __thr_onc_control = PTHREAD_ONCE_INIT;   /* insures single execution */
+pthread_key_t __thr_key;                                /* pthread key */
+void _thr_onc_init();                                   /* creates pthread key */
+void _thr_onc_term(void*);                              /* key destructor function */
 #endif
-struct opaque_auth _null_auth;
-#ifdef FD_SETSIZE
+
+/* these are only used in an out of memory situation... */
+static fd_set __g_svc_fdset;
+static struct opaque_auth __g_null_auth;
+static struct rpc_createerr_t __g_rpc_createerr_t;
+
+/* per-thread global variables encapsulated in one block, makes TLS mgmt easier */
+struct __thr_rpc_vars {
+    fd_set _svc_fdset;
+    struct opaque_auth __null_auth;
+    struct rpc_createerr_t _rpc_createerr_t;
+};
+
+#ifdef WIN32
+
+DWORD __thr_key;
+
+struct __thr_rpc_vars* _get_thr_rpc_vars()
+{
+    struct __thr_rpc_vars* ptr = TlsGetValue(__thr_key);
+
+    if (!ptr && (ptr=malloc(sizeof(struct __thr_rpc_vars)))) {
+        memset(ptr,0,sizeof(struct __thr_rpc_vars));
+        TlsSetValue(__thr_key, ptr);
+    }
+    else if (!ptr) {
+        nt_rpc_report("out of memory");
+    }
+    return ptr;
+}
+
+#else
+
+struct __thr_rpc_vars* _get_thr_rpc_vars()
+{
+    struct __thr_rpc_vars* ptr = NULL;
+
+    pthread_once(&__thr_onc_control, _thr_onc_init);
+    ptr = pthread_getspecific(__thr_key);
+    if (!ptr && ptr=malloc(sizeof(struct __thr_rpc_vars))) {
+        memset(ptr,0,sizeof(struct __thr_rpc_vars));
+        pthread_setspecific(__thr_key, ptr);
+    }
+    else if (!ptr) {
+        fprintf(stderr,"_get_thr_rpc_vars: out of memory");
+    }
+    return ptr;
+}
+
+void _thr_onc_init()
+{
+    pthread_key_create(&__thr_key, _thr_onc_term);
+}
+
+void _thr_onc_term(void*)
+{
+    void* ptr = pthread_getspecific(__thr_key);
+    if (ptr)
+        free(ptr);
+}
+
+#endif
+
 #if defined(WIN32) && defined(__BORLANDC__)
-__declspec(dllexport)
+#define ONC_EXPORT __declspec(dllexport)
+#else
+#define ONC_EXPORT
 #endif
-fd_set onc_svc_fdset;
+
+ONC_EXPORT struct opaque_auth* _thr_null_auth(void)
+{
+    struct __thr_rpc_vars* ptr = _get_thr_rpc_vars();
+    return ptr ? &(ptr->__null_auth) : &__g_null_auth;
+}
+
+ONC_EXPORT struct rpc_createerr_t* _thr_rpc_createerr(void)
+{
+    struct __thr_rpc_vars* ptr = _get_thr_rpc_vars();
+    return ptr ? &(ptr->_rpc_createerr_t) : &__g_rpc_createerr_t;
+}
+
+#ifdef FD_SETSIZE
+
+ONC_EXPORT fd_set* _thr_svc_fdset(void)
+{
+    struct __thr_rpc_vars* ptr = _get_thr_rpc_vars();
+    return ptr ? &(ptr->_svc_fdset) : &__g_svc_fdset;
+}
+
 #else
+
 int svc_fds;
+
 #endif /* def FD_SETSIZE */
-#if defined(WIN32) && defined(__BORLANDC__)
-__declspec(dllexport)
-#endif
-struct rpc_createerr rpc_createerr;
+
diff --git a/oncrpc/svc.c b/oncrpc/svc.c
index 14d64ba..7bbdf7c 100644
--- a/oncrpc/svc.c
+++ b/oncrpc/svc.c
@@ -121,9 +121,9 @@ xprt_register(xprt)
 	}
 
 
-	if (onc_svc_fdset.fd_count < FD_SETSIZE) {
+	if (svc_fdset.fd_count < FD_SETSIZE) {
 		xports[sock] = xprt;
-		FD_SET(sock, &onc_svc_fdset);
+		FD_SET(sock, &svc_fdset);
 	} else {
 		char str[256];
 		
@@ -133,7 +133,7 @@ xprt_register(xprt)
 #else
 	if (sock < FD_SETSIZE) {
 		xports[sock] = xprt;
-		FD_SET(sock, &onc_svc_fdset);
+		FD_SET(sock, &svc_fdset);
 	}
 #endif
 #else
@@ -142,7 +142,6 @@ xprt_register(xprt)
 		svc_fds |= (1 << sock);
 	}
 #endif /* def FD_SETSIZE */
-
 }
 
 /*
@@ -158,11 +157,11 @@ xprt_unregister(xprt)
 #ifdef WIN32
 	if ((xports[sock] == xprt)) {
 		xports[sock] = (SVCXPRT *)0;
-		FD_CLR((unsigned)sock, &onc_svc_fdset);
+		FD_CLR((unsigned)sock, &svc_fdset);
 #else
 	if ((sock < FD_SETSIZE) && (xports[sock] == xprt)) {
 		xports[sock] = (SVCXPRT *)0;
-		FD_CLR(sock, &onc_svc_fdset);
+		FD_CLR(sock, &svc_fdset);
 #endif
 	}
 #else
diff --git a/oncrpc/svc_run.c b/oncrpc/svc_run.c
index 471ecd0..e3a67eb 100644
--- a/oncrpc/svc_run.c
+++ b/oncrpc/svc_run.c
@@ -68,7 +68,7 @@ svc_run()
 
 	for (;;) {
 #ifdef FD_SETSIZE
-		readfds = onc_svc_fdset;
+		readfds = svc_fdset;
 #else
 		readfds = svc_fds;
 #endif /* def FD_SETSIZE */

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-shibboleth/shibboleth-sp2.git



More information about the Pkg-shibboleth-devel mailing list