From owner-svn-src-stable@FreeBSD.ORG Wed Jul 8 01:41:42 2009 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 1D99A1065674; Wed, 8 Jul 2009 01:41:42 +0000 (UTC) (envelope-from delphij@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 0AB618FC0A; Wed, 8 Jul 2009 01:41:42 +0000 (UTC) (envelope-from delphij@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n681ffu2034577; Wed, 8 Jul 2009 01:41:41 GMT (envelope-from delphij@svn.freebsd.org) Received: (from delphij@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n681ffiI034575; Wed, 8 Jul 2009 01:41:41 GMT (envelope-from delphij@svn.freebsd.org) Message-Id: <200907080141.n681ffiI034575@svn.freebsd.org> From: Xin LI Date: Wed, 8 Jul 2009 01:41:41 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r195431 - in stable/7/lib/libc: . rpc X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 08 Jul 2009 01:41:42 -0000 Author: delphij Date: Wed Jul 8 01:41:41 2009 New Revision: 195431 URL: http://svn.freebsd.org/changeset/base/195431 Log: MFC r194932 Lock around access to nc_file and netconfig_info ("ni"). The RPC part of libc is still not thread safe but this would at least reduce the problems we have. PR: threads/118544 Submitted by: Changming Sun Modified: stable/7/lib/libc/ (props changed) stable/7/lib/libc/rpc/getnetconfig.c Modified: stable/7/lib/libc/rpc/getnetconfig.c ============================================================================== --- stable/7/lib/libc/rpc/getnetconfig.c Wed Jul 8 01:09:12 2009 (r195430) +++ stable/7/lib/libc/rpc/getnetconfig.c Wed Jul 8 01:41:41 2009 (r195431) @@ -130,7 +130,11 @@ static struct netconfig *dup_ncp(struct static FILE *nc_file; /* for netconfig db */ +static pthread_mutex_t nc_file_lock = PTHREAD_MUTEX_INITIALIZER; + static struct netconfig_info ni = { 0, 0, NULL, NULL}; +static pthread_mutex_t ni_lock = PTHREAD_MUTEX_INITIALIZER; + #define MAXNETCONFIGLINE 1000 @@ -204,14 +208,24 @@ setnetconfig() * For multiple calls, i.e. nc_file is not NULL, we just return the * handle without reopening the netconfig db. */ + mutex_lock(&ni_lock); ni.ref++; + mutex_unlock(&ni_lock); + + mutex_lock(&nc_file_lock); if ((nc_file != NULL) || (nc_file = fopen(NETCONFIG, "r")) != NULL) { nc_vars->valid = NC_VALID; nc_vars->flag = 0; nc_vars->nc_configs = ni.head; + mutex_unlock(&nc_file_lock); return ((void *)nc_vars); } + mutex_unlock(&nc_file_lock); + + mutex_lock(&ni_lock); ni.ref--; + mutex_unlock(&ni_lock); + nc_error = NC_NONETCONFIG; free(nc_vars); return (NULL); @@ -234,14 +248,18 @@ void *handlep; char *stringp; /* tmp string pointer */ struct netconfig_list *list; struct netconfig *np; + struct netconfig *result; /* * Verify that handle is valid */ + mutex_lock(&nc_file_lock); if (ncp == NULL || nc_file == NULL) { nc_error = NC_NOTINIT; + mutex_unlock(&nc_file_lock); return (NULL); } + mutex_unlock(&nc_file_lock); switch (ncp->valid) { case NC_VALID: @@ -255,7 +273,9 @@ void *handlep; */ if (ncp->flag == 0) { /* first time */ ncp->flag = 1; + mutex_lock(&ni_lock); ncp->nc_configs = ni.head; + mutex_unlock(&ni_lock); if (ncp->nc_configs != NULL) /* entry already exist */ return(ncp->nc_configs->ncp); } @@ -268,7 +288,13 @@ void *handlep; * If we cannot find the entry in the list and is end of file, * we give up. */ - if (ni.eof == 1) return(NULL); + mutex_lock(&ni_lock); + if (ni.eof == 1) { + mutex_unlock(&ni_lock); + return(NULL); + } + mutex_unlock(&ni_lock); + break; default: nc_error = NC_NOTINIT; @@ -289,13 +315,18 @@ void *handlep; /* * Read a line from netconfig file. */ + mutex_lock(&nc_file_lock); do { if (fgets(stringp, MAXNETCONFIGLINE, nc_file) == NULL) { free(stringp); + mutex_lock(&ni_lock); ni.eof = 1; + mutex_unlock(&ni_lock); + mutex_unlock(&nc_file_lock); return (NULL); } } while (*stringp == '#'); + mutex_unlock(&nc_file_lock); list = (struct netconfig_list *) malloc(sizeof (struct netconfig_list)); if (list == NULL) { @@ -325,6 +356,7 @@ void *handlep; * Reposition the current pointer of the handle to the last entry * in the list. */ + mutex_lock(&ni_lock); if (ni.head == NULL) { /* first entry */ ni.head = ni.tail = list; } @@ -333,7 +365,9 @@ void *handlep; ni.tail = ni.tail->next; } ncp->nc_configs = ni.tail; - return(ni.tail->ncp); + result = ni.tail->ncp; + mutex_unlock(&ni_lock); + return(result); } } @@ -367,7 +401,9 @@ void *handlep; nc_handlep->valid = NC_INVALID; nc_handlep->flag = 0; nc_handlep->nc_configs = NULL; + mutex_lock(&ni_lock); if (--ni.ref > 0) { + mutex_unlock(&ni_lock); free(nc_handlep); return(0); } @@ -380,6 +416,8 @@ void *handlep; ni.eof = ni.ref = 0; ni.head = NULL; ni.tail = NULL; + mutex_unlock(&ni_lock); + while (q) { p = q->next; if (q->ncp->nc_lookups != NULL) free(q->ncp->nc_lookups); @@ -390,8 +428,11 @@ void *handlep; } free(nc_handlep); + mutex_lock(&nc_file_lock); fclose(nc_file); nc_file = NULL; + mutex_unlock(&nc_file_lock); + return (0); } @@ -439,15 +480,20 @@ getnetconfigent(netid) * If all the netconfig db has been read and placed into the list and * there is no match for the netid, return NULL. */ + mutex_lock(&ni_lock); if (ni.head != NULL) { for (list = ni.head; list; list = list->next) { if (strcmp(list->ncp->nc_netid, netid) == 0) { + mutex_unlock(&ni_lock); return(dup_ncp(list->ncp)); } } - if (ni.eof == 1) /* that's all the entries */ + if (ni.eof == 1) { /* that's all the entries */ + mutex_unlock(&ni_lock); return(NULL); + } } + mutex_unlock(&ni_lock); if ((file = fopen(NETCONFIG, "r")) == NULL) {