move BaseUI::_name into EventLoop; rename access method in EventLoop as event_loop_na...
[ardour.git] / libs / pbd / event_loop.cc
1 /*
2     Copyright (C) 2012 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include "pbd/event_loop.h"
21 #include "pbd/stacktrace.h"
22
23 using namespace PBD;
24 using namespace std;
25
26 static void do_not_delete_the_loop_pointer (void*) { }
27
28 Glib::Threads::Private<EventLoop> EventLoop::thread_event_loop (do_not_delete_the_loop_pointer);
29
30 EventLoop::EventLoop (string const& name)
31         : _name (name)
32 {
33 }
34
35 EventLoop*
36 EventLoop::get_event_loop_for_thread() {
37         return thread_event_loop.get ();
38 }
39
40 void
41 EventLoop::set_event_loop_for_thread (EventLoop* loop)
42 {
43         thread_event_loop.set (loop);
44 }
45
46 void*
47 EventLoop::invalidate_request (void* data)
48 {
49         InvalidationRecord* ir = (InvalidationRecord*) data;
50
51         /* Some of the requests queued with an EventLoop may involve functors
52          * that make method calls to objects whose lifetime is shorter
53          * than the EventLoop's. We do not want to make those calls if the
54          * object involve has been destroyed. To prevent this, we
55          * provide a way to invalidate those requests when the object is
56          * destroyed.
57          *
58          * An object was passed to __invalidator() which added a callback to
59          * EventLoop::invalidate_request() to its "notify when destroyed"
60          * list. __invalidator() returned an InvalidationRecord that has been
61          * to passed to this function as data.
62          *
63          * The object is currently being destroyed and so we want to
64          * mark all requests involving this object that are queued with
65          * any EventLoop as invalid.
66          *
67          * As of April 2012, we are usign sigc::trackable as the base object
68          * used to queue calls to ::invalidate_request() to be made upon
69          * destruction, via its ::add_destroy_notify_callback() API. This is
70          * not necessarily ideal, but it is very close to precisely what we
71          * want, and many of the objects we want to do this with already
72          * inherit (indirectly) from sigc::trackable.
73          */
74
75         if (ir->event_loop) {
76                 Glib::Threads::Mutex::Lock lm (ir->event_loop->slot_invalidation_mutex());
77                 for (list<BaseRequestObject*>::iterator i = ir->requests.begin(); i != ir->requests.end(); ++i) {
78                         (*i)->valid = false;
79                         (*i)->invalidation = 0;
80                 }
81                 delete ir;
82         }
83
84         return 0;
85 }
86