This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.
Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Hi! Calling getservbyname_r in different threads at the same time results in crashes. The culprit seems to be unguarded static ypall_foreach and ypall_data variables. I wonder why they are needed, is there something in sunrpc that would preclude this from working (I don't see any problems in clnttcp_call and generally, unless the data pointer passed to the callback is ever different from the data pointer passed to clnt_call, there cannot be problems (the first field in the structure is still u_long, so even if some function assumes it is an u_long, it should work))? The following patch certainly fixes the problem for me and in current (limited) testing did not show up any issues. 2004-05-25 Jakub Jelinek <jakub@redhat.com> * nis/ypclnt.c (ypall_data, ypall_foreach): Remove. (struct ypresp_all_data): New type. (__xdr_ypresp_all): Change second argument to struct ypresp_all_data *. Replace ypall_foreach and ypall_data with objp->foreach and objp->data. (yp_all): Remove status variable, add data. Replace all uses of status with data.status. Initialize data.foreach and data.data instead of ypall_foreach and ypall_data. --- libc/nis/ypclnt.c.jj 2004-02-12 11:52:31.000000000 +0100 +++ libc/nis/ypclnt.c 2004-05-25 14:34:53.657850959 +0200 @@ -618,12 +618,16 @@ yp_order (const char *indomain, const ch return YPERR_SUCCESS; } -static void *ypall_data; -static int (*ypall_foreach) (int status, char *key, int keylen, - char *val, int vallen, char *data); +struct ypresp_all_data +{ + unsigned long status; + void *data; + int (*foreach) (int status, char *key, int keylen, + char *val, int vallen, char *data); +}; static bool_t -__xdr_ypresp_all (XDR *xdrs, u_long *objp) +__xdr_ypresp_all (XDR *xdrs, struct ypresp_all_data *objp) { while (1) { @@ -633,13 +637,13 @@ __xdr_ypresp_all (XDR *xdrs, u_long *obj if (!xdr_ypresp_all (xdrs, &resp)) { xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp); - *objp = YP_YPERR; + objp->status = YP_YPERR; return FALSE; } if (resp.more == 0) { xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp); - *objp = YP_NOMORE; + objp->status = YP_NOMORE; return TRUE; } @@ -656,24 +660,24 @@ __xdr_ypresp_all (XDR *xdrs, u_long *obj But we are allowed to add data behind the buffer, if we don't modify the length. So add an extra NUL character to avoid trouble with broken code. */ - *objp = YP_TRUE; + objp->status = YP_TRUE; memcpy (key, resp.ypresp_all_u.val.key.keydat_val, keylen); key[keylen] = '\0'; memcpy (val, resp.ypresp_all_u.val.val.valdat_val, vallen); val[vallen] = '\0'; xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp); - if ((*ypall_foreach) (*objp, key, keylen, - val, vallen, ypall_data)) + if ((*objp->foreach) (objp->status, key, keylen, + val, vallen, objp->data)) return TRUE; } break; default: - *objp = resp.ypresp_all_u.val.stat; + objp->status = resp.ypresp_all_u.val.stat; xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp); /* Sun says we don't need to make this call, but must return immediatly. Since Solaris makes this call, we will call the callback function, too. */ - (*ypall_foreach) (*objp, NULL, 0, NULL, 0, ypall_data); + (*objp->foreach) (objp->status, NULL, 0, NULL, 0, objp->data); return TRUE; } } @@ -689,7 +693,7 @@ yp_all (const char *indomain, const char enum clnt_stat result; struct sockaddr_in clnt_sin; CLIENT *clnt; - unsigned long status; + struct ypresp_all_data data; int clnt_sock; int saved_errno = errno; @@ -725,12 +729,12 @@ yp_all (const char *indomain, const char req.domain = (char *) indomain; req.map = (char *) inmap; - ypall_foreach = incallback->foreach; - ypall_data = (void *) incallback->data; + data.foreach = incallback->foreach; + data.data = (void *) incallback->data; result = clnt_call (clnt, YPPROC_ALL, (xdrproc_t) xdr_ypreq_nokey, (caddr_t) &req, (xdrproc_t) __xdr_ypresp_all, - (caddr_t) &status, RPCTIMEOUT); + (caddr_t) &data, RPCTIMEOUT); if (result != RPC_SUCCESS) { @@ -744,10 +748,10 @@ yp_all (const char *indomain, const char clnt_destroy (clnt); - if (res == YPERR_SUCCESS && status != YP_NOMORE) + if (res == YPERR_SUCCESS && data.status != YP_NOMORE) { __set_errno (saved_errno); - return ypprot_err (status); + return ypprot_err (data.status); } ++try; } Jakub
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |