Ardour  8.12
event_loop.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2009-2016 Paul Davis <paul@linuxaudiosystems.com>
3  * Copyright (C) 2015-2017 Robin Gareus <robin@gareus.org>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program 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
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 #ifndef __pbd_event_loop_h__
21 #define __pbd_event_loop_h__
22 
23 #include <atomic>
24 #include <string>
25 #include <vector>
26 #include <map>
27 #include <boost/function.hpp>
28 #include <boost/bind.hpp> /* we don't need this here, but anything calling call_slot() probably will, so this is convenient */
29 #include <stdint.h>
30 #include <pthread.h>
31 #include <glibmm/threads.h>
32 
33 #include "pbd/libpbd_visibility.h"
34 
35 namespace PBD
36 {
37 
48 {
49 public:
50  EventLoop (std::string const&);
51  virtual ~EventLoop();
52 
53  enum RequestType {
54  range_guarantee = ~0
55  };
56 
57  struct BaseRequestObject;
58 
60  std::list<BaseRequestObject*> requests;
62  std::atomic<int> _valid;
63  std::atomic<int> _ref;
64  const char* file;
65  int line;
66 
67  InvalidationRecord() : event_loop (0), _valid (1), _ref (0) {}
68  void invalidate () { _valid.store (0); }
69  bool valid () { return _valid.load () == 1; }
70 
71  void ref () { _ref.fetch_add (1); }
72  void unref () { (void) _ref.fetch_sub (1); }
73  bool in_use () { return _ref.load () > 0; }
74  int use_count () { return _ref.load (); }
75  };
76 
77  static void* invalidate_request (void* data);
78 
82  boost::function<void()> the_slot;
83 
84  BaseRequestObject() : invalidation (0) {}
86  if (invalidation) {
87  invalidation->unref ();
88  }
89  }
90  };
91 
92  virtual bool call_slot (InvalidationRecord*, const boost::function<void()>&) = 0;
93  virtual Glib::Threads::RWLock& slot_invalidation_rwlock() = 0;
94 
95  std::string event_loop_name() const { return _name; }
96 
99 
101  pthread_t emitting_thread;
102  size_t num_requests;
103  };
104 
105  static std::vector<ThreadBufferMapping> get_request_buffers_for_target_thread (const std::string&);
106 
107  static void pre_register (const std::string& emitting_thread_name, uint32_t num_requests);
108  static void remove_request_buffer_from_map (pthread_t);
109 
110  std::list<InvalidationRecord*> trash;
111 
112  static InvalidationRecord* __invalidator (sigc::trackable& trackable, const char*, int);
113 
114 private:
115  static Glib::Threads::Private<EventLoop> thread_event_loop;
116  std::string _name;
117 
118  typedef std::vector<ThreadBufferMapping> ThreadRequestBufferList;
120  static Glib::Threads::Mutex thread_buffer_requests_lock;
121 
123 
124  /* @param name : name of object/entity that will/may accept
125  * requests from other threads, via a request buffer.
126  */
127  std::string name;
128 
129  /* @param factory : a function that can be called (with an
130  * argument specifying the @param number_of_requests) to create and
131  * return a request buffer for communicating with @p name)
132  */
133  void* (*factory)(uint32_t nunber_of_requests);
134  };
135  typedef std::vector<RequestBufferSupplier> RequestBufferSuppliers;
137 };
138 
139 }
140 
141 #define MISSING_INVALIDATOR nullptr // used to mark places where we fail to provide an invalidator
142 
143 #endif /* __pbd_event_loop_h__ */
EventLoop(std::string const &)
virtual Glib::Threads::RWLock & slot_invalidation_rwlock()=0
std::vector< RequestBufferSupplier > RequestBufferSuppliers
Definition: event_loop.h:135
static void remove_request_buffer_from_map(pthread_t)
virtual ~EventLoop()
static RequestBufferSuppliers request_buffer_suppliers
Definition: event_loop.h:136
std::string event_loop_name() const
Definition: event_loop.h:95
static std::vector< ThreadBufferMapping > get_request_buffers_for_target_thread(const std::string &)
static InvalidationRecord * __invalidator(sigc::trackable &trackable, const char *, int)
std::vector< ThreadBufferMapping > ThreadRequestBufferList
Definition: event_loop.h:118
static Glib::Threads::Mutex thread_buffer_requests_lock
Definition: event_loop.h:120
static void set_event_loop_for_thread(EventLoop *ui)
static void pre_register(const std::string &emitting_thread_name, uint32_t num_requests)
std::list< InvalidationRecord * > trash
Definition: event_loop.h:110
static EventLoop * get_event_loop_for_thread()
static Glib::Threads::Private< EventLoop > thread_event_loop
Definition: event_loop.h:115
static ThreadRequestBufferList thread_buffer_requests
Definition: event_loop.h:119
std::string _name
Definition: event_loop.h:116
virtual bool call_slot(InvalidationRecord *, const boost::function< void()> &)=0
static void * invalidate_request(void *data)
#define LIBPBD_API
Definition: axis_view.h:42
InvalidationRecord * invalidation
Definition: event_loop.h:81
boost::function< void()> the_slot
Definition: event_loop.h:82
std::list< BaseRequestObject * > requests
Definition: event_loop.h:60