]> granicus.if.org Git - libtirpc/commitdiff
libtirpc-0.1.10 - fix rpc_createerr tsd create
authorIan Kent <ikent@redhat.com>
Mon, 20 Apr 2009 13:44:28 +0000 (09:44 -0400)
committerSteve Dickson <steved@redhat.com>
Mon, 20 Apr 2009 13:44:28 +0000 (09:44 -0400)
The pthread_getspecific() call returns either the address of the tsd or
NULL and a call to pthread_getspecific() on a key value not obtained by a
call to pthread_key_create() is undefined.

The pthread_key_create() call returns either zero or a negative error
code.

So the __rpc_createerr() routine looks kinda broken.

Signed-off-by: Ian Kent <ikent@redhat.com>
Signed-off-by: Steve Dickson <steved@redhat.com>
src/mt_misc.c

index 5c4d7cd23ef41d1ffcbc23d4003f7402449a2281..5da6015592b4f50a2eaaa8ae366607b03e082cf8 100644 (file)
@@ -91,27 +91,24 @@ struct rpc_createerr *
 __rpc_createerr()
 {
        static thread_key_t rce_key = -1;
-       struct rpc_createerr *rce_addr = 0;
+       struct rpc_createerr *rce_addr;
 
-       if ((rce_addr = (struct rpc_createerr *)thr_getspecific(rce_key))
-                       != (struct rpc_createerr *)-1) {
-               mutex_lock(&tsd_lock);
-               if (thr_keycreate(&rce_key, free) != -1) {
-                       mutex_unlock(&tsd_lock);
-                       return (&rpc_createerr);
-               }
-               mutex_unlock(&tsd_lock);
-       }
+       mutex_lock(&tsd_lock);
+       if (rce_key == -1)
+               thr_keycreate(&rce_key, free);
+       mutex_unlock(&tsd_lock);
+
+       rce_addr = (struct rpc_createerr *)thr_getspecific(rce_key);
        if (!rce_addr) {
                rce_addr = (struct rpc_createerr *)
                        malloc(sizeof (struct rpc_createerr));
-               if (thr_setspecific(rce_key, (void *) rce_addr) != 0) {
+               if (!rce_addr ||
+                   thr_setspecific(rce_key, (void *) rce_addr) != 0) {
                        if (rce_addr)
                                free(rce_addr);
                        return (&rpc_createerr);
                }
                memset(rce_addr, 0, sizeof (struct rpc_createerr));
-               return (rce_addr);
        }
        return (rce_addr);
 }