Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src Our hdestroy implementation was non-conformant because it fr...
details: https://anonhg.NetBSD.org/src/rev/4be67dc477d1
branches: trunk
changeset: 330755:4be67dc477d1
user: christos <christos%NetBSD.org@localhost>
date: Sun Jul 20 13:34:17 2014 +0000
description:
Our hdestroy implementation was non-conformant because it freed the key of
each entry. Add a new function hdestroy1 that allows the user to control
what gets freed. Pointed out by Pedro Giffuni at FreeBSD.
diffstat:
include/search.h | 6 ++-
lib/libc/stdlib/Makefile.inc | 3 +-
lib/libc/stdlib/hcreate.3 | 91 ++++++++++++++++++++++++++-----------------
lib/libc/stdlib/hcreate.c | 27 ++++++++++--
4 files changed, 82 insertions(+), 45 deletions(-)
diffs (266 lines):
diff -r b2e1a1583dbe -r 4be67dc477d1 include/search.h
--- a/include/search.h Sun Jul 20 13:34:14 2014 +0000
+++ b/include/search.h Sun Jul 20 13:34:17 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: search.h,v 1.20 2013/04/27 21:35:25 joerg Exp $ */
+/* $NetBSD: search.h,v 1.21 2014/07/20 13:34:17 christos Exp $ */
/*
* Written by J.T. Conklin <jtc%NetBSD.org@localhost>
@@ -62,8 +62,12 @@
ENTRY *hsearch(ENTRY, ACTION);
#ifdef _NETBSD_SOURCE
+#define FREE_KEY 1
+#define FREE_DATA 2
+void hdestroy1(int);
int hcreate_r(size_t, struct hsearch_data *);
void hdestroy_r(struct hsearch_data *);
+void hdestroy1_r(struct hsearch_data *, int);
int hsearch_r(ENTRY, ACTION, ENTRY **, struct hsearch_data *);
#endif /* _NETBSD_SOURCE */
diff -r b2e1a1583dbe -r 4be67dc477d1 lib/libc/stdlib/Makefile.inc
--- a/lib/libc/stdlib/Makefile.inc Sun Jul 20 13:34:14 2014 +0000
+++ b/lib/libc/stdlib/Makefile.inc Sun Jul 20 13:34:17 2014 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile.inc,v 1.81 2014/01/08 02:15:42 christos Exp $
+# $NetBSD: Makefile.inc,v 1.82 2014/07/20 13:34:17 christos Exp $
# from: @(#)Makefile.inc 8.3 (Berkeley) 2/4/95
# stdlib sources
@@ -66,6 +66,7 @@
MLINKS+=getenv.3 getenv_r.3
MLINKS+=hcreate.3 hdestroy.3 hcreate.3 hsearch.3
MLINKS+=hcreate.3 hcreate_r.3 hcreate.3 hdestroy_r.3 hcreate.3 hsearch_r.3
+MLINKS+=hcreate.3 hdestroy1.3 hcreate.3 hdestroy1_r.3
MLINKS+=insque.3 remque.3
MLINKS+=lsearch.3 lfind.3
MLINKS+=malloc.3 calloc.3 malloc.3 realloc.3 malloc.3 free.3
diff -r b2e1a1583dbe -r 4be67dc477d1 lib/libc/stdlib/hcreate.3
--- a/lib/libc/stdlib/hcreate.3 Sun Jul 20 13:34:14 2014 +0000
+++ b/lib/libc/stdlib/hcreate.3 Sun Jul 20 13:34:17 2014 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: hcreate.3,v 1.10 2011/09/15 09:14:54 wiz Exp $
+.\" $NetBSD: hcreate.3,v 1.11 2014/07/20 13:34:17 christos Exp $
.\"
.\" Copyright (c) 1999 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -27,14 +27,16 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd September 14, 2011
+.Dd July 20, 2014
.Dt HCREATE 3
.Os
.Sh NAME
.Nm hcreate ,
.Nm hcreate_r ,
.Nm hdestroy ,
+.Nm hdestroy1 ,
.Nm hdestroy_r ,
+.Nm hdestroy1_r ,
.Nm hsearch ,
.Nm hsearch_r
.Nd manage hash search table
@@ -49,7 +51,11 @@
.Ft void
.Fn hdestroy "void"
.Ft void
+.Fn hdestroy1 "int flags"
+.Ft void
.Fn hdestroy_r "struct hsearch_data *table"
+.Ft void
+.Fn hdestroy1_r "struct hsearch_data *table" "int flags"
.Ft ENTRY *
.Fn hsearch "ENTRY item" "ACTION action"
.Ft int
@@ -60,6 +66,8 @@
.Fn hcreate_r ,
.Fn hdestroy ,
.Fn hdestroy_r
+.Fn hdestroy1 ,
+.Fn hdestroy1_r
.Fn hsearch ,
and
.Fn hsearch_r
@@ -141,33 +149,49 @@
.Fa item .
.El
.Pp
-Note that the comparison
-.Fa key
-must be allocated using
-.Xr malloc 3
-or
-.Xr calloc 3
-if action is
-.Dv ENTER
-and
+The traditional
.Fn hdestroy
-will be called.
-This is because
-.Fn hdestroy
-will call
+and
+.Fn hdestroy_r
+functions don't
.Xr free 3
-for each comparison
+the data associated with the
+.Fa key
+and
+.Fa value
+of each entry, because they did not allocate them.
+Since there is no
+.Dq iterator
+function provided, the
+.Fn hdestroy1
+and
+.Fn hdestroy1_r
+allow controlling if the
.Fa key
-(but not
-.Fa data ) .
-Typically the comparison
+or
+.Fa value
+will be freed using the
+.Fa flags
+argument.
+If the bit
+.Dv FREE_KEY
+is set, then the
.Fa key
-is allocated by using
-.Xr strdup 3 .
+of each entry will be
+passed to
+.Xr free 3 .
+If the bit
+.Dv FREE_VALUE
+is set, then the
+.Fa value
+of each entry will be
+passed to
+.Xr free 3 .
.Pp
The
.Fn hcreate_r ,
.Fn hdestroy_r ,
+.Fn hdestroy1_r ,
and
.Fn hsearch_r
functions are re-entrant versions of the above functions that can
@@ -266,6 +290,7 @@
.Xr bsearch 3 ,
.Xr lsearch 3 ,
.Xr malloc 3 ,
+.Xr free 3 ,
.Xr strcmp 3
.Sh STANDARDS
The
@@ -291,6 +316,13 @@
functions are
.Tn GNU
extensions.
+The
+.Fn hdestroy1
+and
+.Fn hdestroy1_r
+are
+.Nx
+extensions.
.Sh CAVEATS
At least the following limitations can be mentioned:
.Bl -bullet
@@ -301,20 +333,5 @@
.It
Individual hash table entries can be added, but not deleted.
.It
-The standard is indecipherable about the
-internal memory usage of the functions,
-mentioning only that
-.Do
-.Fn hcreate
-and
-.Fn hsearch
-functions may use
-.Fn malloc
-to allocate space
-.Dc .
-This limits the portability of the functions,
-given that other implementations may not
-.Xr free 3
-the buffer pointed by
-.Fa key .
+There is no iterator to scan for all entries in the table.
.El
diff -r b2e1a1583dbe -r 4be67dc477d1 lib/libc/stdlib/hcreate.c
--- a/lib/libc/stdlib/hcreate.c Sun Jul 20 13:34:14 2014 +0000
+++ b/lib/libc/stdlib/hcreate.c Sun Jul 20 13:34:17 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: hcreate.c,v 1.8 2011/09/17 16:54:39 christos Exp $ */
+/* $NetBSD: hcreate.c,v 1.9 2014/07/20 13:34:17 christos Exp $ */
/*
* Copyright (c) 2001 Christopher G. Demetriou
@@ -43,7 +43,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: hcreate.c,v 1.8 2011/09/17 16:54:39 christos Exp $");
+__RCSID("$NetBSD: hcreate.c,v 1.9 2014/07/20 13:34:17 christos Exp $");
#endif /* LIBC_SCCS and not lint */
#if !defined(lint)
@@ -141,14 +141,20 @@
}
void
-hdestroy(void)
+hdestroy1(int flags)
{
_DIAGASSERT(htable.table != NULL);
- hdestroy_r(&htable);
+ hdestroy1_r(&htable, flags);
}
void
-hdestroy_r(struct hsearch_data *head)
+hdestroy(void)
+{
+ hdestroy1(0);
+}
+
+void
+hdestroy1_r(struct hsearch_data *head, int flags)
{
struct internal_entry *ie;
size_t idx;
@@ -166,13 +172,22 @@
while (!SLIST_EMPTY(&table[idx])) {
ie = SLIST_FIRST(&table[idx]);
SLIST_REMOVE_HEAD(&table[idx], link);
- free(ie->ent.key);
+ if (flags & FREE_KEY)
+ free(ie->ent.key);
+ if (flags & FREE_DATA)
+ free(ie->ent.data);
free(ie);
}
}
free(table);
}
+void
+hdestroy_r(struct hsearch_data *head)
+{
+ hdestroy1_r(head, 0);
+}
+
ENTRY *
hsearch(ENTRY item, ACTION action)
{
Home |
Main Index |
Thread Index |
Old Index