From 656485c1f1487775ccb0c223c4f5809f8daa7fcc Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Mon, 28 May 2007 17:35:15 +0000 Subject: [PATCH] Make URI structures reference-counted. --- src/core/download.c | 4 ++-- src/core/open.c | 9 ++++++--- src/core/uri.c | 2 +- src/include/gpxe/open.h | 3 --- src/include/gpxe/uri.h | 25 +++++++++++++++++++------ 5 files changed, 28 insertions(+), 15 deletions(-) diff --git a/src/core/download.c b/src/core/download.c index 4522bf2c..e3f77794 100644 --- a/src/core/download.c +++ b/src/core/download.c @@ -121,7 +121,7 @@ int start_download ( const char *uri_string, struct async *parent, err: async_uninit ( &download->async ); ufree ( download->buffer.addr ); - free_uri ( download->uri ); + uri_put ( download->uri ); free ( download ); return rc; } @@ -150,7 +150,7 @@ static void download_sigchld ( struct async *async, /* Discard the buffer */ ufree ( download->buffer.addr ); } - free_uri ( download->uri ); + uri_put ( download->uri ); download->uri = NULL; /* Terminate ourselves */ diff --git a/src/core/open.c b/src/core/open.c index b61160eb..6c184e65 100644 --- a/src/core/open.c +++ b/src/core/open.c @@ -52,6 +52,7 @@ static struct socket_opener socket_openers_end[0] int xfer_open_uri ( struct xfer_interface *xfer, const char *uri_string ) { struct uri *uri; struct uri_opener *opener; + int rc = -ENOTSUP; DBGC ( xfer, "XFER %p opening URI %s\n", xfer, uri_string ); @@ -61,14 +62,16 @@ int xfer_open_uri ( struct xfer_interface *xfer, const char *uri_string ) { for ( opener = uri_openers ; opener < uri_openers_end ; opener++ ) { if ( strcmp ( uri->scheme, opener->scheme ) == 0 ) { - return opener->open ( xfer, uri ); + rc = opener->open ( xfer, uri ); + goto done; } } DBGC ( xfer, "XFER %p attempted to open unsupported URI scheme " "\"%s\"\n", xfer, uri->scheme ); - free_uri ( uri ); - return -ENOTSUP; + done: + uri_put ( uri ); + return rc; } /** diff --git a/src/core/uri.c b/src/core/uri.c index cb1ac3bc..6ebc6373 100644 --- a/src/core/uri.c +++ b/src/core/uri.c @@ -35,7 +35,7 @@ * * Splits a URI into its component parts. The return URI structure is * dynamically allocated and must eventually be freed by calling - * free_uri(). + * uri_put(). */ struct uri * parse_uri ( const char *uri_string ) { struct uri *uri; diff --git a/src/include/gpxe/open.h b/src/include/gpxe/open.h index b16bbe88..5e368486 100644 --- a/src/include/gpxe/open.h +++ b/src/include/gpxe/open.h @@ -46,9 +46,6 @@ struct uri_opener { * @v xfer Data transfer interface * @v uri URI * @ret rc Return status code - * - * This method takes ownership of the URI structure, and is - * responsible for eventually calling free_uri(). */ int ( * open ) ( struct xfer_interface *xfer, struct uri *uri ); }; diff --git a/src/include/gpxe/uri.h b/src/include/gpxe/uri.h index b8c7e098..6fddcc33 100644 --- a/src/include/gpxe/uri.h +++ b/src/include/gpxe/uri.h @@ -8,6 +8,7 @@ */ #include +#include /** A Uniform Resource Identifier * @@ -37,6 +38,8 @@ * query = "what=is", fragment = "this" */ struct uri { + /** Reference count */ + struct refcnt refcnt; /** Scheme */ const char *scheme; /** Opaque part */ @@ -100,15 +103,25 @@ static inline int uri_has_relative_path ( struct uri *uri ) { } /** - * Free URI structure + * Increment URI reference count * * @v uri URI - * - * Frees all the dynamically-allocated storage used by the URI - * structure. + * @ret uri URI */ -static inline void free_uri ( struct uri *uri ) { - free ( uri ); +static inline __attribute__ (( always_inline )) struct uri * +uri_get ( struct uri *uri ) { + ref_get ( &uri->refcnt ); + return uri; +} + +/** + * Decrement URI reference count + * + * @v uri URI + */ +static inline __attribute__ (( always_inline )) void +uri_put ( struct uri *uri ) { + ref_put ( &uri->refcnt ); } extern struct uri * parse_uri ( const char *uri_string );