[beast: 54/73] BSE: SF2: use std::shared_ptr for blob reference counting
- From: Tim Janik <timj src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [beast: 54/73] BSE: SF2: use std::shared_ptr for blob reference counting
- Date: Thu, 23 Mar 2017 21:46:13 +0000 (UTC)
commit f8fe2cfc4dd68eb181230c2509a862ce063edc3c
Author: Stefan Westerfeld <stefan space twc de>
Date: Thu Dec 8 16:43:54 2016 +0100
BSE: SF2: use std::shared_ptr for blob reference counting
Signed-off-by: Stefan Westerfeld <stefan space twc de>
bse/bsesoundfont.cc | 57 +++++++++---------------
bse/bsesoundfont.hh | 5 +-
bse/bsesoundfontrepo.cc | 3 +-
bse/bsestorage.cc | 109 +++++++++++++++--------------------------------
bse/bsestorage.hh | 31 +++++++++----
5 files changed, 81 insertions(+), 124 deletions(-)
---
diff --git a/bse/bsesoundfont.cc b/bse/bsesoundfont.cc
index 4296787..2926173 100644
--- a/bse/bsesoundfont.cc
+++ b/bse/bsesoundfont.cc
@@ -30,7 +30,6 @@ static GQuark quark_load_sound_font = 0;
static void
bse_sound_font_init (BseSoundFont *sound_font)
{
- sound_font->blob = NULL;
sound_font->sfont_id = -1;
sound_font->sfrepo = NULL;
}
@@ -56,11 +55,12 @@ bse_sound_font_get_property (GObject *object,
GParamSpec *pspec)
{
BseSoundFont *sound_font = BSE_SOUND_FONT (object);
+ Bse::SoundFontImpl *sound_font_impl = sound_font->as<Bse::SoundFontImpl *>();
switch (param_id)
{
case PARAM_FILE_NAME:
- if (sound_font->blob)
- sfi_value_set_string (value, bse_storage_blob_file_name (sound_font->blob));
+ if (sound_font_impl->blob)
+ sfi_value_set_string (value, bse_storage_blob_file_name (sound_font_impl->blob));
else
sfi_value_set_string (value, NULL);
break;
@@ -90,14 +90,7 @@ bse_sound_font_finalize (GObject *object)
{
BseSoundFont *sound_font = BSE_SOUND_FONT (object);
- /* free blob */
- if (sound_font->blob)
- {
- bse_storage_blob_unref (sound_font->blob);
- sound_font->blob = NULL;
- }
-
- if (sound_font->sfrepo != NULL || sound_font->blob != NULL || sound_font->sfont_id != -1)
+ if (sound_font->sfrepo != NULL || sound_font->sfont_id != -1)
g_warning (G_STRLOC ": some resources could not be freed.");
/* chain parent class' handler */
@@ -105,10 +98,12 @@ bse_sound_font_finalize (GObject *object)
}
Bse::Error
-bse_sound_font_load_blob (BseSoundFont *self,
- BseStorageBlob *blob,
- gboolean init_presets)
+bse_sound_font_load_blob (BseSoundFont *self,
+ BseStorage::BlobP blob,
+ gboolean init_presets)
{
+ Bse::SoundFontImpl *sound_font_impl = self->as<Bse::SoundFontImpl *>();
+
if (self->sfrepo == NULL)
{
self->sfrepo = BSE_SOUND_FONT_REPO (BSE_ITEM (self)->parent);
@@ -119,13 +114,6 @@ bse_sound_font_load_blob (BseSoundFont *self,
g_return_val_if_fail (self->sfrepo != NULL, Bse::Error::INTERNAL);
g_return_val_if_fail (self->sfont_id == -1, Bse::Error::INTERNAL);
- bse_storage_blob_ref (blob);
- if (self->blob)
- {
- bse_storage_blob_unref (self->blob);
- self->blob = NULL;
- }
-
std::lock_guard<Bse::Mutex> guard (bse_sound_font_repo_mutex (self->sfrepo));
fluid_synth_t *fluid_synth = bse_sound_font_repo_fluid_synth (self->sfrepo);
int sfont_id = fluid_synth_sfload (fluid_synth, bse_storage_blob_file_name (blob), 0);
@@ -149,12 +137,12 @@ bse_sound_font_load_blob (BseSoundFont *self,
}
}
self->sfont_id = sfont_id;
- self->blob = blob;
+ sound_font_impl->blob = blob;
error = Bse::Error::NONE;
}
else
{
- bse_storage_blob_unref (blob);
+ sound_font_impl->blob = nullptr;
error = Bse::Error::WAVE_NOT_FOUND;
}
return error;
@@ -178,9 +166,11 @@ bse_sound_font_unload (BseSoundFont *sound_font)
Bse::Error
bse_sound_font_reload (BseSoundFont *sound_font)
{
+ Bse::SoundFontImpl *sound_font_impl = sound_font->as<Bse::SoundFontImpl *>();
+
g_return_val_if_fail (sound_font->sfont_id == -1, Bse::Error::INTERNAL);
- return bse_sound_font_load_blob (sound_font, sound_font->blob, FALSE);
+ return bse_sound_font_load_blob (sound_font, sound_font_impl->blob, FALSE);
}
static void
@@ -188,19 +178,20 @@ bse_sound_font_store_private (BseObject *object,
BseStorage *storage)
{
BseSoundFont *sound_font = BSE_SOUND_FONT (object);
+ Bse::SoundFontImpl *sound_font_impl = sound_font->as<Bse::SoundFontImpl *>();
/* chain parent class' handler */
BSE_OBJECT_CLASS (parent_class)->store_private (object, storage);
- if (!BSE_STORAGE_SELF_CONTAINED (storage) && !bse_storage_blob_is_temp_file (sound_font->blob))
+ if (!BSE_STORAGE_SELF_CONTAINED (storage) && !bse_storage_blob_is_temp_file (sound_font_impl->blob))
{
bse_storage_break (storage);
- bse_storage_printf (storage, "(load-sound-font \"%s\")", bse_storage_blob_file_name
(sound_font->blob));
+ bse_storage_printf (storage, "(load-sound-font \"%s\")", bse_storage_blob_file_name
(sound_font_impl->blob));
}
else
{
bse_storage_break (storage);
bse_storage_printf (storage, "(load-sound-font ");
- bse_storage_put_blob (storage, sound_font->blob);
+ bse_storage_put_blob (storage, sound_font_impl->blob);
bse_storage_printf (storage, ")");
}
}
@@ -222,7 +213,7 @@ bse_sound_font_restore_private (BseObject *object,
quark = g_quark_try_string (scanner->next_value.v_identifier);
if (quark == quark_load_sound_font)
{
- BseStorageBlob *blob;
+ BseStorage::BlobP blob;
Bse::Error error;
g_scanner_get_next_token (scanner); /* eat quark identifier */
@@ -233,17 +224,12 @@ bse_sound_font_restore_private (BseObject *object,
}
else
{
- GTokenType token = bse_storage_parse_blob (storage, &blob);
+ GTokenType token = bse_storage_parse_blob (storage, blob);
if (token != G_TOKEN_NONE)
- {
- if (blob)
- bse_storage_blob_unref (blob);
- return token;
- }
+ return token;
}
if (g_scanner_peek_next_token (scanner) != ')')
{
- bse_storage_blob_unref (blob);
return GTokenType (')');
}
parse_or_return (scanner, ')');
@@ -251,7 +237,6 @@ bse_sound_font_restore_private (BseObject *object,
if (error != 0)
bse_storage_warn (storage, "failed to load sound font \"%s\": %s",
bse_storage_blob_file_name (blob), bse_error_blurb (error));
- bse_storage_blob_unref (blob);
expected_token = G_TOKEN_NONE; /* got ')' */
}
else /* chain parent class' handler */
diff --git a/bse/bsesoundfont.hh b/bse/bsesoundfont.hh
index c0af024..23c34a8 100644
--- a/bse/bsesoundfont.hh
+++ b/bse/bsesoundfont.hh
@@ -14,7 +14,6 @@
#define BSE_SOUND_FONT_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS ((object), BSE_TYPE_SOUND_FONT,
BseSoundFontClass))
struct BseSoundFont : BseContainer {
- BseStorageBlob *blob;
int sfont_id;
BseSoundFontRepo *sfrepo;
GList *presets;
@@ -23,7 +22,7 @@ struct BseSoundFontClass : BseContainerClass
{};
Bse::Error bse_sound_font_load_blob (BseSoundFont *sound_font,
- BseStorageBlob *blob,
+ BseStorage::BlobP blob,
gboolean init_presets);
void bse_sound_font_unload (BseSoundFont *sound_font);
Bse::Error bse_sound_font_reload (BseSoundFont *sound_font);
@@ -31,6 +30,8 @@ Bse::Error bse_sound_font_reload (BseSoundFont *sound_font)
namespace Bse {
class SoundFontImpl : public ContainerImpl, public virtual SoundFontIface {
+public:
+ BseStorage::BlobP blob;
protected:
virtual ~SoundFontImpl ();
public:
diff --git a/bse/bsesoundfontrepo.cc b/bse/bsesoundfontrepo.cc
index e0e08e8..2a204e8 100644
--- a/bse/bsesoundfontrepo.cc
+++ b/bse/bsesoundfontrepo.cc
@@ -374,9 +374,8 @@ repo_load_file (BseSoundFontRepo *sfrepo, const String &file_name, BseSoundFont
BseSoundFont *sound_font = (BseSoundFont*) bse_object_new (BSE_TYPE_SOUND_FONT, "uname", fname.c_str(),
NULL);
bse_container_add_item (BSE_CONTAINER (sfrepo), BSE_ITEM (sound_font));
- BseStorageBlob *blob = bse_storage_blob_new_from_file (file_name.c_str(), FALSE);
+ BseStorage::BlobP blob = bse_storage_blob_new_from_file (file_name.c_str(), FALSE);
Error error = bse_sound_font_load_blob (sound_font, blob, TRUE);
- bse_storage_blob_unref (blob);
if (error == Bse::Error::NONE)
{
diff --git a/bse/bsestorage.cc b/bse/bsestorage.cc
index 6f1c354..b3ec778 100644
--- a/bse/bsestorage.cc
+++ b/bse/bsestorage.cc
@@ -42,14 +42,6 @@ struct _BseStorageItemLink
BseItem *to_item;
gchar *error;
};
-struct _BseStorageBlob
-{
- Bse::Mutex mutex;
- char *file_name;
- int ref_count;
- gboolean is_temp_file;
- gulong id;
-};
/* --- prototypes --- */
static void bse_storage_init (BseStorage *self);
@@ -241,8 +233,6 @@ bse_storage_reset (BseStorage *self)
self->dblocks = NULL;
self->n_dblocks = 0;
- for (auto blob : self->data.blobs)
- bse_storage_blob_unref (blob);
self->data.blobs.clear();
g_free (self->free_me);
@@ -274,10 +264,10 @@ bse_storage_add_dblock (BseStorage *self,
}
static gulong
-bse_storage_add_blob (BseStorage *self,
- BseStorageBlob *blob)
+bse_storage_add_blob (BseStorage *self,
+ BseStorage::BlobP blob)
{
- self->data.blobs.push_back (bse_storage_blob_ref (blob));
+ self->data.blobs.push_back (blob);
return self->data.blobs.back()->id;
}
@@ -1810,24 +1800,10 @@ bse_storage_parse_data_handle_rest (BseStorage *self,
// == blobs ==
-BseStorageBlob *
-bse_storage_blob_ref (BseStorageBlob *blob)
-{
- g_return_val_if_fail (blob != NULL, NULL);
- g_return_val_if_fail (blob->ref_count > 0, NULL);
-
- blob->mutex.lock();
- blob->ref_count++;
- blob->mutex.unlock();
-
- return blob;
-}
-
const gchar *
-bse_storage_blob_file_name (BseStorageBlob *blob)
+bse_storage_blob_file_name (BseStorage::BlobP blob)
{
g_return_val_if_fail (blob != NULL, NULL);
- g_return_val_if_fail (blob->ref_count > 0, NULL);
blob->mutex.lock();
const gchar *file_name = blob->file_name;
@@ -1836,29 +1812,16 @@ bse_storage_blob_file_name (BseStorageBlob *blob)
return file_name;
}
-void
-bse_storage_blob_unref (BseStorageBlob *blob)
+BseStorage::Blob::~Blob()
{
- g_return_if_fail (blob != NULL);
- g_return_if_fail (blob->ref_count > 0);
-
- blob->mutex.lock();
- blob->ref_count--;
- gboolean destroy = blob->ref_count == 0;
- blob->mutex.unlock();
- if (destroy)
+ if (is_temp_file)
{
- if (blob->is_temp_file)
- {
- unlink (blob->file_name);
- /* FIXME: check error code and do what? */
- }
- g_free (blob->file_name);
- blob->file_name = NULL;
- bse_id_free (blob->id);
- blob->mutex.~Mutex();
- g_free (blob);
+ unlink (file_name);
+ /* FIXME: check error code and do what? */
}
+ g_free (file_name);
+ file_name = NULL;
+ bse_id_free (id);
}
/* search in /tmp for files called "bse-<user>-<pid>*"
@@ -1893,24 +1856,21 @@ bse_storage_blob_clean_files()
}
}
-BseStorageBlob *
+BseStorage::BlobP
bse_storage_blob_new_from_file (const char *file_name,
gboolean is_temp_file)
{
- BseStorageBlob *blob = g_new0 (BseStorageBlob, 1);
- new (&blob->mutex) Bse::Mutex();
+ BseStorage::BlobP blob = std::make_shared<BseStorage::Blob>(); // FIXME: constructor
blob->file_name = g_strdup (file_name);
- blob->ref_count = 1;
blob->is_temp_file = is_temp_file;
blob->id = bse_id_alloc();
return blob;
}
gboolean
-bse_storage_blob_is_temp_file (BseStorageBlob *blob)
+bse_storage_blob_is_temp_file (BseStorage::BlobP blob)
{
g_return_val_if_fail (blob != NULL, FALSE);
- g_return_val_if_fail (blob->ref_count > 0, FALSE);
blob->mutex.lock();
gboolean is_temp_file = blob->is_temp_file;
@@ -1919,19 +1879,19 @@ bse_storage_blob_is_temp_file (BseStorageBlob *blob)
return is_temp_file;
}
-typedef struct
+struct WStoreBlob
{
- BseStorageBlob *blob;
- BseStorage *storage;
- int fd;
-} WStoreBlob;
+ BseStorage::BlobP blob;
+ BseStorage *storage;
+ int fd;
+};
static WStoreBlob *
-wstore_blob_new (BseStorage *storage,
- BseStorageBlob *blob)
+wstore_blob_new (BseStorage *storage,
+ BseStorage::BlobP blob)
{
- WStoreBlob *wsb = (WStoreBlob *) g_new0 (WStoreBlob, 1);
- wsb->blob = bse_storage_blob_ref (blob);
+ WStoreBlob *wsb = new WStoreBlob();
+ wsb->blob = blob;
wsb->storage = storage;
wsb->fd = -1;
return wsb;
@@ -1970,12 +1930,12 @@ wstore_blob_destroy (gpointer data)
WStoreBlob *wblob = (WStoreBlob *) data;
if (wblob->fd >= 0)
close (wblob->fd);
- bse_storage_blob_unref (wblob->blob);
+ delete wblob;
}
void
-bse_storage_put_blob (BseStorage *self,
- BseStorageBlob *blob)
+bse_storage_put_blob (BseStorage *self,
+ BseStorage::BlobP blob)
{
if (BSE_STORAGE_DBLOCK_CONTAINED (self))
{
@@ -1997,14 +1957,14 @@ bse_storage_put_blob (BseStorage *self,
GTokenType
bse_storage_parse_blob (BseStorage *self,
- BseStorageBlob **blob)
+ BseStorage::BlobP &blob_out)
{
GScanner *scanner = bse_storage_get_scanner (self);
int bse_fd = -1;
int tmp_fd = -1;
char *file_name = g_strdup_format ("%s/bse-%s-%u-%08x", g_get_tmp_dir(), g_get_user_name(), getpid(),
g_random_int());
- *blob = NULL; /* on error, the resulting blob should be NULL */
+ blob_out = nullptr; /* on error, the resulting blob should be NULL */
parse_or_return (scanner, '(');
parse_or_return (scanner, G_TOKEN_IDENTIFIER);
@@ -2072,7 +2032,7 @@ bse_storage_parse_blob (BseStorage *self,
}
close (bse_fd);
close (tmp_fd);
- *blob = bse_storage_blob_new_from_file (file_name, TRUE);
+ blob_out = bse_storage_blob_new_from_file (file_name, TRUE);
g_free (file_name);
}
else if (g_quark_try_string (scanner->value.v_identifier) == quark_blob_id)
@@ -2080,13 +2040,14 @@ bse_storage_parse_blob (BseStorage *self,
gulong id;
parse_or_return (scanner, G_TOKEN_INT);
id = scanner->value.v_int64;
- *blob = NULL;
- for (auto b : self->data.blobs)
+ blob_out = NULL;
+ for (auto blob : self->data.blobs)
{
- if (b->id == id)
- *blob = bse_storage_blob_ref (b);
+ if (blob->id == id)
+ blob_out = blob;
+;
}
- if (!*blob)
+ if (!blob_out)
{
g_warning ("failed to lookup storage blob with id=%ld\n", id);
goto return_with_error;
diff --git a/bse/bsestorage.hh b/bse/bsestorage.hh
index 22aeee4..db7ace5 100644
--- a/bse/bsestorage.hh
+++ b/bse/bsestorage.hh
@@ -37,7 +37,6 @@ typedef enum /*< skip >*/
/* --- BseStorage --- */
typedef struct _BseStorageDBlock BseStorageDBlock;
typedef struct _BseStorageItemLink BseStorageItemLink;
-typedef struct _BseStorageBlob BseStorageBlob;
typedef void (*BseStorageRestoreLink) (gpointer data,
BseStorage *storage,
BseItem *from_item,
@@ -65,14 +64,28 @@ struct BseStorage : BseObject {
gfloat osc_freq;
guint n_channels;
+ /* storage blob */
+ struct Blob {
+ Bse::Mutex mutex;
+ char *file_name;
+ gboolean is_temp_file;
+ gulong id;
+
+ ~Blob();
+ };
+
+ typedef std::shared_ptr<Blob> BlobP;
+
/* C++ allocated data */
struct Data {
- std::vector<BseStorageBlob *> blobs;
+ std::vector<BlobP> blobs;
} data;
};
struct BseStorageClass : BseObjectClass
{};
+typedef struct BseStorage::Blob BseStorageBlob;
+
/* --- compatibility file parsing --- */
void bse_storage_compat_dhreset (BseStorage *self);
void bse_storage_compat_dhmixf (BseStorage *self,
@@ -121,7 +134,7 @@ void bse_storage_put_data_handle (BseStorage *self,
guint significant_bits,
GslDataHandle *dhandle);
void bse_storage_put_blob (BseStorage *self,
- BseStorageBlob *blob);
+ BseStorage::BlobP blob);
void bse_storage_put_xinfos (BseStorage *self,
gchar **xinfos);
Bse::Error bse_storage_flush_fd (BseStorage *self,
@@ -164,18 +177,16 @@ GTokenType bse_storage_parse_rest (BseStorage *self,
BseTryStatement try_statement,
gpointer user_data);
GTokenType bse_storage_parse_blob (BseStorage *self,
- BseStorageBlob **blob);
+ BseStorage::BlobP &blob);
gboolean bse_storage_check_parse_negate (BseStorage *self);
/* --- bse storage blob --- */
-BseStorageBlob *bse_storage_blob_ref (BseStorageBlob *self);
-const gchar *bse_storage_blob_file_name (BseStorageBlob *self);
-gboolean bse_storage_blob_is_temp_file (BseStorageBlob *self);
-void bse_storage_blob_unref (BseStorageBlob *self);
-BseStorageBlob *bse_storage_blob_new_from_file (const gchar *file_name,
+const gchar *bse_storage_blob_file_name (BseStorage::BlobP self);
+gboolean bse_storage_blob_is_temp_file (BseStorage::BlobP self);
+BseStorage::BlobP bse_storage_blob_new_from_file (const gchar *file_name,
gboolean is_temp_file);
-void bse_storage_blob_clean_files (void);
+void bse_storage_blob_clean_files (void);
/* --- short-hands --- */
#define bse_storage_get_scanner(s) ((s)->rstore->scanner)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]