aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2009-12-31 10:02:55 +0100
committerMax Kellermann <max@duempel.org>2009-12-31 18:27:35 +0100
commitaad05fd1386442330ecc0a15b86cf8081ea47c83 (patch)
tree66e9063f50b1c78cb8dda928e511f84f02f95891 /src
parent032c5376ad0ad8dca135d210363ef8e454e11167 (diff)
downloadmpd-aad05fd1386442330ecc0a15b86cf8081ea47c83.tar.gz
mpd-aad05fd1386442330ecc0a15b86cf8081ea47c83.tar.xz
mpd-aad05fd1386442330ecc0a15b86cf8081ea47c83.zip
archive: use reference counting for archive+input
Make the input_stream implementation hold a reference on the archive_file object. Allow the caller to "close" the archive_file object immediately, no matter if the open_stream() method has succeeded or not.
Diffstat (limited to 'src')
-rw-r--r--src/archive/bz2_archive_plugin.c9
-rw-r--r--src/archive/iso9660_archive_plugin.c12
-rw-r--r--src/archive/zzip_archive_plugin.c11
-rw-r--r--src/archive_plugin.h3
-rw-r--r--src/input/archive_input_plugin.c5
5 files changed, 32 insertions, 8 deletions
diff --git a/src/archive/bz2_archive_plugin.c b/src/archive/bz2_archive_plugin.c
index 975fd3f07..e4a5c3664 100644
--- a/src/archive/bz2_archive_plugin.c
+++ b/src/archive/bz2_archive_plugin.c
@@ -25,6 +25,7 @@
#include "archive/bz2_archive_plugin.h"
#include "archive_api.h"
#include "input_plugin.h"
+#include "refcount.h"
#include <stdint.h>
#include <stddef.h>
@@ -40,6 +41,8 @@
struct bz2_archive_file {
struct archive_file base;
+ struct refcount ref;
+
char *name;
bool reset;
struct input_stream istream;
@@ -105,6 +108,7 @@ bz2_open(const char *pathname, GError **error_r)
context = g_malloc(sizeof(*context));
archive_file_init(&context->base, &bz2_archive_plugin);
+ refcount_init(&context->ref);
//open archive
if (!input_stream_open(&context->istream, pathname, error_r)) {
@@ -149,6 +153,9 @@ bz2_close(struct archive_file *file)
{
struct bz2_archive_file *context = (struct bz2_archive_file *) file;
+ if (!refcount_dec(&context->ref))
+ return;
+
g_free(context->name);
input_stream_close(&context->istream);
@@ -180,6 +187,8 @@ bz2_open_stream(struct archive_file *file, struct input_stream *is,
bis->eof = false;
+ refcount_inc(&context->ref);
+
return true;
}
diff --git a/src/archive/iso9660_archive_plugin.c b/src/archive/iso9660_archive_plugin.c
index 3d5f33896..0d32b9b1b 100644
--- a/src/archive/iso9660_archive_plugin.c
+++ b/src/archive/iso9660_archive_plugin.c
@@ -25,6 +25,7 @@
#include "archive/iso9660_archive_plugin.h"
#include "archive_api.h"
#include "input_plugin.h"
+#include "refcount.h"
#include <cdio/cdio.h>
#include <cdio/iso9660.h>
@@ -37,6 +38,8 @@
struct iso9660_archive_file {
struct archive_file base;
+ struct refcount ref;
+
iso9660_t *iso;
GSList *list;
GSList *iter;
@@ -93,6 +96,7 @@ iso9660_archive_open(const char *pathname, GError **error_r)
g_new(struct iso9660_archive_file, 1);
archive_file_init(&context->base, &iso9660_archive_plugin);
+ refcount_init(&context->ref);
context->list = NULL;
@@ -139,8 +143,11 @@ iso9660_archive_close(struct archive_file *file)
{
struct iso9660_archive_file *context =
(struct iso9660_archive_file *)file;
-
GSList *tmp;
+
+ if (!refcount_dec(&context->ref))
+ return;
+
if (context->list) {
//free list
for (tmp = context->list; tmp != NULL; tmp = g_slist_next(tmp))
@@ -192,6 +199,9 @@ iso9660_archive_open_stream(struct archive_file *file, struct input_stream *is,
is->size = iis->statbuf->size;
iis->max_blocks = CEILING(iis->statbuf->size, ISO_BLOCKSIZE);
+
+ refcount_inc(&context->ref);
+
return true;
}
diff --git a/src/archive/zzip_archive_plugin.c b/src/archive/zzip_archive_plugin.c
index fb7af74ed..755baff74 100644
--- a/src/archive/zzip_archive_plugin.c
+++ b/src/archive/zzip_archive_plugin.c
@@ -26,6 +26,7 @@
#include "archive_api.h"
#include "archive_api.h"
#include "input_plugin.h"
+#include "refcount.h"
#include <zzip/zzip.h>
#include <glib.h>
@@ -34,6 +35,8 @@
struct zzip_archive {
struct archive_file base;
+ struct refcount ref;
+
ZZIP_DIR *dir;
GSList *list;
GSList *iter;
@@ -56,6 +59,7 @@ zzip_archive_open(const char *pathname, GError **error_r)
ZZIP_DIRENT dirent;
archive_file_init(&context->base, &zzip_archive_plugin);
+ refcount_init(&context->ref);
// open archive
context->list = NULL;
@@ -102,6 +106,10 @@ static void
zzip_archive_close(struct archive_file *file)
{
struct zzip_archive *context = (struct zzip_archive *) file;
+
+ if (!refcount_dec(&context->ref))
+ return;
+
if (context->list) {
//free list
for (GSList *tmp = context->list; tmp != NULL; tmp = g_slist_next(tmp))
@@ -151,6 +159,9 @@ zzip_archive_open_stream(struct archive_file *file, struct input_stream *is,
zzip_file_stat(zis->file, &z_stat);
is->size = z_stat.st_size;
+
+ refcount_inc(&context->ref);
+
return true;
}
diff --git a/src/archive_plugin.h b/src/archive_plugin.h
index 52629f2e1..b15320503 100644
--- a/src/archive_plugin.h
+++ b/src/archive_plugin.h
@@ -67,9 +67,6 @@ struct archive_plugin {
/**
* Opens an input_stream of a file within the archive.
*
- * If this function succeeds, then the #input_stream "owns"
- * the archive file and will automatically close it.
- *
* @param path the path within the archive
* @param error_r location to store the error occuring, or
* NULL to ignore errors
diff --git a/src/input/archive_input_plugin.c b/src/input/archive_input_plugin.c
index 248b8626e..0409057bb 100644
--- a/src/input/archive_input_plugin.c
+++ b/src/input/archive_input_plugin.c
@@ -67,12 +67,9 @@ input_archive_open(struct input_stream *is, const char *pathname,
//setup fileops
opened = archive_file_open_stream(file, is, filename, error_r);
+ archive_file_close(file);
g_free(pname);
- if (!opened) {
- archive_file_close(file);
- }
-
return opened;
}