Skip Menu |
 

Subject: wshelper initialization of thread local storage
Cc: dongq@MIT.EDU
After trying to find out why krb_mk_req was failing for the AFS plugin, I
ran into a problem with wshelper. Rgethostbyname() was returning NULL for
every query from the plugin thread. This was because
TlsGetValue(dwGhnIndex) was returning NULL.

Thread local storage seems to be getting initialized in wshelper at
DLL_THREAD_ATTACH. However, the docs say :

"Note that a DLL's entry-point function is called with this
(DLL_THREAD_ATTACH) value only by threads created after the DLL is loaded by
the process. When a DLL is loaded using LoadLibrary, existing threads do not
call the entry-point function of the newly loaded DLL."

It appears that the TLS can be left uninitialized for the AFS plugin thread
depending on when the thread is created.

Asanka
What needs to be done here is that any call to TlsGetValue() that
returns NULL should result in a call to AllocateThreadLocalMemory()
followed by a subsequent call to TlsGetValue().

AllocateThreadLocalMemory() should CreateMutex() a named mutex and then
test for its prior existence to determine whether or not the body of the
function should be executed. The body of the function should perform a
TlsGetValue() and only if it returns NULL should it actually allocate
the the memory.
Please review the attached patch. Allocating the memory within the
thread is obviously thread safe and therefore does not require mutexes.
? Debug
? obj
? rs_state.ini
Index: dllmain.c
===================================================================
RCS file: /cvs/pismere/pismere/athena/wshelper/wshelper/dllmain.c,v
retrieving revision 1.4
diff -u -r1.4 dllmain.c
--- dllmain.c 28 Oct 2005 23:14:09 -0000 1.4
+++ dllmain.c 15 Dec 2005 14:58:40 -0000
@@ -99,15 +99,15 @@
if (lpvData != NULL)
TlsSetValue(dwHesPwNamIndex, lpvData);

- lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct passwd));
+ lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct passwd));
if (lpvData != NULL)
TlsSetValue(dwHesPwUidIndex, lpvData);

- lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct hostent));
+ lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct hostent));
if (lpvData != NULL)
TlsSetValue(dwGhnIndex, lpvData);

- lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct hostent));
+ lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct hostent));
if (lpvData != NULL)
TlsSetValue(dwGhaIndex, lpvData);

Index: gethna.c
===================================================================
RCS file: /cvs/pismere/pismere/athena/wshelper/wshelper/gethna.c,v
retrieving revision 1.8
diff -u -r1.8 gethna.c
--- gethna.c 16 Nov 2005 21:23:01 -0000 1.8
+++ gethna.c 15 Dec 2005 14:58:40 -0000
@@ -108,13 +108,21 @@
DNS_STATUS status;
const char *cp;
char queryname[DNS_MAX_NAME_BUFFER_LENGTH ];
+#ifdef DEBUG
char debstr[80];
+#endif
char** domain;
struct in_addr host_addr;

host = (struct hostent*)(TlsGetValue(dwGhnIndex));
- if (host == NULL)
- return NULL;
+ if (host == NULL) {
+ LPVOID lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct hostent));
+ if (lpvData != NULL) {
+ TlsSetValue(dwGhnIndex, lpvData);
+ host = (struct hostent*)lpvData;
+ } else
+ return NULL;
+ }

if (host->h_name == NULL)
host->h_name = LocalAlloc(LPTR, DNS_MAX_LABEL_BUFFER_LENGTH);
@@ -255,7 +263,9 @@
{
DNS_STATUS status;
struct hostent* host;
+#ifdef DEBUG
char debstr[80];
+#endif

PDNS_RECORD pDnsRecord;
DNS_FREE_TYPE freetype ;
@@ -294,8 +304,14 @@
}

host = (struct hostent*)(TlsGetValue(dwGhaIndex));
- if (host == NULL)
- return NULL;
+ if (host == NULL) {
+ LPVOID lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct hostent));
+ if (lpvData != NULL) {
+ TlsSetValue(dwGhaIndex, lpvData);
+ host = (struct hostent*)lpvData;
+ } else
+ return NULL;
+ }

if (host->h_name == NULL)
host->h_name = LocalAlloc(LPTR, DNS_MAX_LABEL_BUFFER_LENGTH);
Index: hesmailh.c
===================================================================
RCS file: /cvs/pismere/pismere/athena/wshelper/wshelper/hesmailh.c,v
retrieving revision 1.3
diff -u -r1.3 hesmailh.c
--- hesmailh.c 16 Nov 2005 21:23:01 -0000 1.3
+++ hesmailh.c 15 Dec 2005 14:58:40 -0000
@@ -55,9 +55,14 @@
if (cp == NULL) return(NULL);

ret = (struct hes_postoffice*)(TlsGetValue(dwHesMailIndex));
-
- if (ret == NULL)
- return NULL;
+ if (ret == NULL) {
+ LPVOID lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct hes_postoffice));
+ if (lpvData != NULL) {
+ TlsSetValue(dwHesMailIndex, lpvData);
+ ret = (struct hes_postoffice*)lpvData;
+ } else
+ return NULL;
+ }
if (!ret->po_type)
ret->po_type = LocalAlloc(LPTR, LINESIZE);
if (!ret->po_host)
Index: hespwnam.c
===================================================================
RCS file: /cvs/pismere/pismere/athena/wshelper/wshelper/hespwnam.c,v
retrieving revision 1.5
diff -u -r1.5 hespwnam.c
--- hespwnam.c 16 Nov 2005 21:23:01 -0000 1.5
+++ hespwnam.c 15 Dec 2005 14:58:40 -0000
@@ -75,8 +75,14 @@
return(NULL);

pw = (struct passwd*)(TlsGetValue(dwHesPwUidIndex));
- if (pw == NULL)
- return NULL;
+ if (pw == NULL) {
+ LPVOID lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct passwd));
+ if (lpvData != NULL) {
+ TlsSetValue(dwHesPwUidIndex, lpvData);
+ pw = (struct passwd*)lpvData;
+ } else
+ return NULL;
+ }

strcpy(buf, pp[0]);
hes_free(pp);
@@ -113,8 +119,14 @@
return(NULL);

pw = (struct passwd*)(TlsGetValue(dwHesPwNamIndex));
- if (pw == NULL)
- return NULL;
+ if (pw == NULL) {
+ LPVOID lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct passwd));
+ if (lpvData != NULL) {
+ TlsSetValue(dwHesPwNamIndex, lpvData);
+ pw = (struct passwd*)lpvData;
+ } else
+ return NULL;
+ }

strcpy(buf, pp[0]);
hes_free(pp);
Index: hesservb.c
===================================================================
RCS file: /cvs/pismere/pismere/athena/wshelper/wshelper/hesservb.c,v
retrieving revision 1.5
diff -u -r1.5 hesservb.c
--- hesservb.c 16 Nov 2005 21:23:01 -0000 1.5
+++ hesservb.c 15 Dec 2005 14:58:40 -0000
@@ -72,8 +72,14 @@
if (cp == NULL)
return(NULL);
p = (struct servent*)(TlsGetValue(dwHesServIndex));
- if (p == NULL)
- return NULL;
+ if (p == NULL) {
+ LPVOID lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct servent));
+ if (lpvData != NULL) {
+ TlsSetValue(dwHesServIndex, lpvData);
+ p = (struct servent*)lpvData;
+ } else
+ return NULL;
+ }
if (!p->s_name)
p->s_name = LocalAlloc(LPTR, DNS_MAX_LABEL_BUFFER_LENGTH);
if (!p->s_proto)