diff options
author | Debarshi Ray <debarshir@src.gnome.org> | 2010-03-01 22:35:50 +0200 |
---|---|---|
committer | Murray Cumming <murrayc@murrayc.com> | 2010-03-08 15:00:47 +0100 |
commit | 3eaaf5bd7e029e261d812ec1d45eae784d479d86 (patch) | |
tree | 76960a75a0d53415909928a064f8ed468a05b61d /gio/src/file.ccg | |
parent | 6978bd38faae5dcb626929334b747f97e644717f (diff) | |
download | glibmm-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.
Diffstat (limited to 'gio/src/file.ccg')
-rw-r--r-- | gio/src/file.ccg | 68 |
1 files changed, 56 insertions, 12 deletions
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); |