3
* Copyright 2003, The libsigc++ Development Team
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Lesser General Public
7
* License as published by the Free Software Foundation; either
8
* version 2.1 of the License, or (at your option) any later version.
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Lesser General Public License for more details.
15
* You should have received a copy of the GNU Lesser General Public
16
* License along with this library; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
#include <sigc++/functors/slot_base.h>
28
// only MSVC needs this to guarantee that all new/delete are executed from the DLL module
29
#ifdef SIGC_NEW_DELETE_IN_LIBRARY_ONLY
30
void* slot_rep::operator new(size_t size_)
35
void slot_rep::operator delete(void* p)
41
void slot_rep::disconnect()
45
call_ = 0; // Invalidate the slot.
46
// _Must_ be done here because parent_ might defer the actual
47
// destruction of the slot_rep and try to invoke it before that point.
48
void* data_ = parent_;
49
parent_ = 0; // Just a precaution.
50
(cleanup_)(data_); // Notify the parent (might lead to destruction of this!).
57
void* slot_rep::notify(void* data)
59
struct destroy_notify_struct
61
destroy_notify_struct() : deleted_(false) { }
63
static void* notify(void* data)
65
destroy_notify_struct* self_ = reinterpret_cast<destroy_notify_struct*>(data);
66
self_->deleted_ = true;
73
slot_rep* self_ = reinterpret_cast<slot_rep*>(data);
75
self_->call_ = 0; // Invalidate the slot.
77
// Make sure we are notified if disconnect() deletes self_, which is trackable.
78
destroy_notify_struct notifier;
79
self_->add_destroy_notify_callback(¬ifier, destroy_notify_struct::notify);
80
self_->disconnect(); // Disconnect the slot (might lead to deletion of self_!).
81
// If self_ has been deleted, the destructor has called destroy().
82
if (!notifier.deleted_)
84
self_->remove_destroy_notify_callback(¬ifier);
85
self_->destroy(); // Detach the stored functor from the other referred trackables and destroy it.
86
// destroy() might lead to deletion of self_. Bug #564005.
91
} // namespace internal
93
slot_base::slot_base()
98
slot_base::slot_base(rep_type* rep)
103
slot_base::slot_base(const slot_base& src)
105
blocked_(src.blocked_)
109
//Check call_ so we can ignore invalidated slots.
110
//Otherwise, destroyed bound reference parameters (whose destruction caused the slot's invalidation) may be used during dup().
111
//Note: I'd prefer to check somewhere during dup(). murrayc.
113
rep_ = src.rep_->dup();
116
*this = slot_base(); //Return the default invalid slot.
121
slot_base::~slot_base()
127
slot_base::operator bool() const
132
slot_base& slot_base::operator=(const slot_base& src)
134
if (src.rep_ == rep_) return *this;
142
internal::slot_rep* new_rep_ = src.rep_->dup();
144
if (rep_) // Silently exchange the slot_rep.
146
new_rep_->set_parent(rep_->parent_, rep_->cleanup_);
155
void slot_base::set_parent(void* parent, void* (*cleanup)(void*)) const
158
rep_->set_parent(parent, cleanup);
161
void slot_base::add_destroy_notify_callback(void* data, func_destroy_notify func) const
164
rep_->add_destroy_notify_callback(data, func);
167
void slot_base::remove_destroy_notify_callback(void* data) const
170
rep_->remove_destroy_notify_callback(data);
173
bool slot_base::block(bool should_block)
176
blocked_ = should_block;
180
bool slot_base::unblock()
185
void slot_base::disconnect()
192
/*bool slot_base::empty() const // having this function not inline is killing performance !!!
194
if (rep_ && !rep_->call_)
196
delete rep_; // This is not strictly necessary here. I'm convinced that it is
197
rep_ = 0; // safe to wait for the destructor to delete the slot_rep. Martin.