summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDebarshi Ray <debarshir@src.gnome.org>2010-03-01 22:35:50 +0200
committerMurray Cumming <murrayc@murrayc.com>2010-03-08 15:00:47 +0100
commit3eaaf5bd7e029e261d812ec1d45eae784d479d86 (patch)
tree76960a75a0d53415909928a064f8ed468a05b61d
parent6978bd38faae5dcb626929334b747f97e644717f (diff)
downloadglibmm-3eaaf5bd7e029e261d812ec1d45eae784d479d86.tar.gz
Bug #611521 - Free Gio::SlotFileProgress (and friends) at completion
The Gio::SlotFileProgress slots (and their friends) used in operations like Gio::File::copy, Gio::File::copy_async and Gio::File::move should not freed when their C callbacks are invoked for the first time. Instead they should be freed after the operation has completed.
-rw-r--r--ChangeLog10
-rw-r--r--gio/src/file.ccg68
2 files changed, 66 insertions, 12 deletions
diff --git a/ChangeLog b/ChangeLog
index a228e08e..7c5f2626 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2010-03-08 Debarshi Ray <debarshi.ray@gmail.com>
+
+ Bug #611521 - Free Gio::SlotFileProgress (and friends) at completion
+
+ * gio/src/file.ccg:
+ The Gio::SlotFileProgress slots (and their friends) used in operations like
+ Gio::File::copy, Gio::File::copy_async and Gio::File::move should not freed
+ when their C callbacks are invoked for the first time. Instead they should be
+ freed after the operation has completed.
+
2010-02-27 Daniel Elstner <daniel.kitta@gmail.com>
Avoid compiler warning in resolver example
diff --git a/gio/src/file.ccg b/gio/src/file.ccg
index 1b6b059d..c539d03d 100644
--- a/gio/src/file.ccg
+++ b/gio/src/file.ccg
@@ -27,6 +27,7 @@
namespace
{
+typedef std::pair<Gio::File::SlotFileProgress*, Gio::SlotAsyncReady*> CopySlots;
typedef std::pair<Gio::File::SlotReadMore*, Gio::SlotAsyncReady*> LoadPartialSlots;
static void
@@ -50,8 +51,37 @@ SignalProxy_file_progress_callback(goffset current_num_bytes,
Glib::exception_handlers_invoke();
}
#endif //GLIBMM_EXCEPTIONS_ENABLED
+}
+
+// Same as SignalProxy_async_callback, except that this one knows that
+// the slot is packed in a pair. The operation is assumed to be finished
+// after the callback is triggered, so we delete that pair here.
+static void
+SignalProxy_file_ready_callback(GObject*, GAsyncResult* res, void* data)
+{
+ CopySlots* slot_pair = static_cast<CopySlots*>(data);
+ Gio::SlotAsyncReady* the_slot = slot_pair->second;
+
+ #ifdef GLIBMM_EXCEPTIONS_ENABLED
+ try
+ {
+ #endif //GLIBMM_EXCEPTIONS_ENABLED
+ if(*the_slot)
+ {
+ Glib::RefPtr<Gio::AsyncResult> result = Glib::wrap(res, true /* take copy */);
+ (*the_slot)(result);
+ }
+ #ifdef GLIBMM_EXCEPTIONS_ENABLED
+ }
+ catch(...)
+ {
+ Glib::exception_handlers_invoke();
+ }
+ #endif //GLIBMM_EXCEPTIONS_ENABLED
delete the_slot;
+ delete slot_pair->first; // progress slot
+ delete slot_pair;
}
static gboolean
@@ -670,6 +700,8 @@ File::copy(const Glib::RefPtr<File>& destination, const SlotFileProgress& slot,
slot_copy,
&gerror);
+ delete slot_copy;
+
#ifdef GLIBMM_EXCEPTIONS_ENABLED
if (gerror)
::Glib::Error::throw_exception(gerror);
@@ -705,6 +737,8 @@ File::copy(const Glib::RefPtr<File>& destination, const SlotFileProgress& slot,
slot_copy,
&gerror);
+ delete slot_copy;
+
#ifdef GLIBMM_EXCEPTIONS_ENABLED
if (gerror)
::Glib::Error::throw_exception(gerror);
@@ -752,11 +786,14 @@ File::copy_async(const Glib::RefPtr<File>& destination,
FileCopyFlags flags,
int io_priority)
{
- // Create copies of slots.
- // Pointers to them will be passed through the callbacks' data parameter
- // and deleted in the corresponding callback.
- SlotAsyncReady* slot_ready_copy = new SlotAsyncReady(slot_ready);
+ // Create a new pair which will hold copies of passed slots.
+ // This will be deleted in the SignalProxy_file_ready_callback() callback
+ CopySlots* slots = new CopySlots();
SlotFileProgress* slot_progress_copy = new SlotFileProgress(slot_progress);
+ SlotAsyncReady* slot_ready_copy = new SlotAsyncReady(slot_ready);
+
+ slots->first = slot_progress_copy;
+ slots->second = slot_ready_copy;
g_file_copy_async(gobj(),
Glib::unwrap(destination),
@@ -765,8 +802,8 @@ File::copy_async(const Glib::RefPtr<File>& destination,
Glib::unwrap(cancellable),
&SignalProxy_file_progress_callback,
slot_progress_copy,
- &SignalProxy_async_callback,
- slot_ready_copy);
+ &SignalProxy_file_ready_callback,
+ slots);
}
void
@@ -799,11 +836,14 @@ File::copy_async(const Glib::RefPtr<File>& destination,
FileCopyFlags flags,
int io_priority)
{
- // Create copies of slots.
- // Pointers to them will be passed through the callbacks' data parameter
- // and deleted in the corresponding callback.
- SlotAsyncReady* slot_ready_copy = new SlotAsyncReady(slot_ready);
+ // Create a new pair which will hold copies of passed slots.
+ // This will be deleted in the SignalProxy_file_ready_callback() callback
+ CopySlots* slots = new CopySlots();
SlotFileProgress* slot_progress_copy = new SlotFileProgress(slot_progress);
+ SlotAsyncReady* slot_ready_copy = new SlotAsyncReady(slot_ready);
+
+ slots->first = slot_progress_copy;
+ slots->second = slot_ready_copy;
g_file_copy_async(gobj(),
Glib::unwrap(destination),
@@ -812,8 +852,8 @@ File::copy_async(const Glib::RefPtr<File>& destination,
0,
&SignalProxy_file_progress_callback,
slot_progress_copy,
- &SignalProxy_async_callback,
- slot_ready_copy);
+ &SignalProxy_file_ready_callback,
+ slots);
}
void
@@ -862,6 +902,8 @@ File::move(const Glib::RefPtr<File>& destination, const SlotFileProgress& slot,
slot_copy,
&gerror);
+ delete slot_copy;
+
#ifdef GLIBMM_EXCEPTIONS_ENABLED
if (gerror)
::Glib::Error::throw_exception(gerror);
@@ -897,6 +939,8 @@ File::move(const Glib::RefPtr<File>& destination, const SlotFileProgress& slot,
slot_copy,
&gerror);
+ delete slot_copy;
+
#ifdef GLIBMM_EXCEPTIONS_ENABLED
if (gerror)
::Glib::Error::throw_exception(gerror);